Power Apps portals で Web ページにカスタムしたテーブルを表示する(2/2)
Power Pages でも使えます。
Power Apps portals は素早く外部公開できるサイトを作成することができますが、設置できるコンポーネントはある程度決まったものとなります。
これが物足りないという場合にはカスタマイズとなるのですが、そのサンプルとして JavaScript と Web API や Liquid を使って Web ページに独自のテーブルを表示してみました。
前回は単純な JavaScript を動作させ、標準のコンポーネントを使わずるところまで作成しました。
今回は、Dataverse からデータを取得して表示するところを作成します。
完成イメージ
Grid.js を使ってテーブルを表示しています。
特になにも変わっていないように見えますが、Dataverse テーブルからデータを取得しています。
前回の記事
事前準備
作業に入る前に、取得するテーブル、列、データ、ビューを作成しておきます。
下記ではソリューションを使っていますが、使う必要はありません。
テーブル
列
データ
ビュー
作業概要(Liquid)
標準コンポーネントを使用せずデータを表示する 1つ目の方法は Liquid を使うことです。
今回は Liquid を使って、画面の読み込み時に Dataverse から任意のデータを取得し、前回作った Script に適用します。
テーブルのアクセス許可設定
まず、Dataverse のテーブルにアクセスするための設定を行います。ここで許可していないテーブルは、標準コンポーネントからもアクセスすることができなくなっています。
-
Studio を起動し、テーブルのアクセス許可をクリックします。
-
新しいアクセス許可をクリック、以下のように入力し保存をクリックします。
項目 | 設定値 |
---|---|
名前 | CustomTableAccess |
テーブル | {事前に作ったテーブル} |
アクセスの種類 | グローバルアクセス |
アクセス許可 | 読み取り |
ロール | 管理者 |
これで、対象のテーブルは、管理者ロールを持つユーザに対してすべてのレコードへのアクセスを許可することになります。
また、アクセスの種類を変更することで、ログインユーザが作成したレコードのみだとか、ログインユーザが所属している取引先企業に関連付けられているレコードのみといった設定が可能ですので、様々なセキュリティの設定を行うことができます。
Web テンプレート (JavaScript 部品)の編集
次に前回作成した、JavaScript を動作させる部分のみを記載した Web テンプレートを編集します。
- ポータル管理アプリ から Web テンプレート をクリックし、CustomTableScript をクリックします。
項目 | 設定値 |
---|---|
名前 | CustomTableScript |
Web サイト | {自身のポータルサイト} |
ソース | 以下に記載 |
<link href="https://unpkg.com/gridjs/dist/theme/mermaid.min.css" rel="stylesheet" />
<script src="https://unpkg.com/gridjs/dist/gridjs.umd.js"></script>
{% comment %} ライブラリの参照 {% endcomment %}
<style>
.my-btn-class {
color: black;
}
.my-btn-class:focus,
.my-btn-class.focus {
color: black;
}
</style>
{% comment %} 競合するスタイルの上書き {% endcomment %}
<script>
document.addEventListener('DOMContentLoaded', async () => {
{% comment %} 変更点ここから {% endcomment %}
let data = [];
let record = [];
{% entityview logical_name:'nan_employee' name:'ポータル用'%}
{% for item in entityview.records %}
record = ["{{item.nan_name | escape }}", "{{item.nan_email | escape }}","{{item.nan_phone_number | escape }}"];
data.push(record);
{% endfor %}
{% endentityview %}
{% comment %} Dataverse からデータを読み取り、JavaScript の配列変数に格納 {% endcomment %}
{% comment %} 変更点ここまで {% endcomment %}
new gridjs.Grid({
columns: ["Name", "EMail", 'Phone Number'],
data: data, {% comment %} 変更点 {% endcomment %}
className: {
paginationButton: "my-btn-class"
},
search: {
enabled: true
},
sort: true,
pagination: {
enabled: true,
limit: 2,
summary: true
},
language: {
"search": {
"placeholder": "🔍 Search..."
},
"pagination": {
"previous": "←",
"next": "→",
"showing": "😃 Displaying",
"results": () => "Records"
}
}
}).render(document.getElementById("gridWrapper"));
}, false);
</script>
{% comment %} Dataverse テーブルデータでの Grid.js の実行 {% endcomment %}
entityview を使って、指定のテーブルからデータを取得し、それを JavaScript の配列変数に格納します。
その後、前回と同じく、Grid.js に適用しています。
動作の確認
最後に動作を確認します。
- 同期の構成、Web サイトの参照 をクリックし表示された画面にの実行結果であるテーブルに、Dataverse の情報が表示されていれば完了です。
作業概要(Web API)
標準コンポーネントを使用せずデータを表示する 2つ目の方法は Web API を使うことです。
Liquid の時と同じの結果になる内容を Web API を使ってやっていきます。
テーブルへのアクセス権限の設定
こちらも同じく、Dataverse のテーブルにアクセスするための設定を行います。
Web API の使用に関する設定
次に、Web API を使用するための設定を行います。ここは、Web API 専用の設定です。
-
ポータル管理アプリ から サイト設定 をクリックし、新規をクリックします。
-
テーブルに対する Web API の有効化を設定します。
項目 | 設定値 |
---|---|
名前 | Webapi/{対象のテーブル}/enabled |
Web サイト | {自身のポータルサイト} |
値 | true |
- テーブルの列に対する Web API の有効化を設定します。
項目 | 設定値 |
---|---|
名前 | Webapi/{対象のテーブル}/fields |
Web サイト | {自身のポータルサイト} |
値 | {対象の列} |
- エラー処理に対するを設定します。
項目 | 設定値 |
---|---|
名前 | Webapi/error/innererror |
Web サイト | {自身のポータルサイト} |
値 | true |
Web テンプレート (JavaScript 部品)の編集
前回作成した、JavaScript を動作させる部分のみを記載した Web テンプレートを編集します。
- ポータル管理アプリ から Web テンプレート をクリックし、CustomTableScript をクリックします。
<link href="https://unpkg.com/gridjs/dist/theme/mermaid.min.css" rel="stylesheet" />
<script src="https://unpkg.com/gridjs/dist/gridjs.umd.js"></script>
{% comment %} ライブラリの参照 {% endcomment %}
<style>
.my-btn-class {
color: black;
}
.my-btn-class:focus,
.my-btn-class.focus {
color: black;
}
</style>
{% comment %} 競合するスタイルの上書き {% endcomment %}
<script>
{% comment %} 変更点ここから {% endcomment %}
(function(webapi, $){
function safeAjax(ajaxOptions) {
var deferredAjax = $.Deferred();
shell.getTokenDeferred().done(function (token) {
// add headers for ajax
if (!ajaxOptions.headers) {
$.extend(ajaxOptions, {
headers: {
"__RequestVerificationToken": token
}
});
} else {
ajaxOptions.headers["__RequestVerificationToken"] = token;
}
$.ajax(ajaxOptions)
.done(function(data, textStatus, jqXHR) {
validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve);
}).fail(deferredAjax.reject); //ajax
}).fail(function () {
deferredAjax.rejectWith(this, arguments); // on token failure, pass the token ajax and args
});
return deferredAjax.promise();
}
webapi.safeAjax = safeAjax;
})(window.webapi = window.webapi || {}, jQuery)
{% comment %} Docs にある CSRF token の取得を含む Api 呼び出しのラッパー関数 {% endcomment %}
{% comment %} 変更点ここまで {% endcomment %}
document.addEventListener('DOMContentLoaded', async () => {
{% comment %} 変更点ここから {% endcomment %}
const res = await webapi.safeAjax({
type: "GET",
url: "/_api/nan_employees?$select=nan_name,nan_email,nan_phone_number",
contentType: "application/json",
success: function (res) {
return res;
}
});
{% comment %} 変更点ここまで {% endcomment %}
new gridjs.Grid({
{% comment %} 変更点ここから {% endcomment %}
columns: ["Name", "EMail", 'Phone Number'],
data: res.value.map(record => [record.nan_name, record.nan_email, record.nan_phone_number]),
{% comment %} 変更点ここまで {% endcomment %}
className: {
paginationButton: "my-btn-class"
},
search: {
enabled: true
},
sort: true,
pagination: {
enabled: true,
limit: 2,
summary: true
},
language: {
"search": {
"placeholder": "🔍 Search..."
},
"pagination": {
"previous": "←",
"next": "→",
"showing": "😃 Displaying",
"results": () => "Records"
}
}
}).render(document.getElementById("gridWrapper"));
}, false);
</script>
{% comment %} Dataverse テーブルデータでの Grid.js の実行 {% endcomment %}
webapi.safeAjax を使って、指定のテーブルからデータを取得し、それを Grid.js に適用しています。
webapi.safeAjax は、データの取得だけであれば必要ありませんが、データの登録や更新、削除を行う場合は getTokenDeferred にて取得できるトークンが必要になってきます。
動作の確認
最後に動作を確認します。
- 同期の構成、Web サイトの参照 をクリックし表示された画面にの実行結果であるテーブルに、Dataverse の情報が表示されていれば完了です。
まとめ
少し設定方法は違いますが、Web API、Liquid いずれでも Dataverse のテーブルにアクセスことができました。
使い分けというか、特徴としては以下かなと思います。
Liquid
- 画面表示時に Dataverse にアクセスするため、待ち時間が少ない(ような気がします)と思います。
- 登録、更新、削除はできないので、標準コンポーネントに任せる必要があります。
Web API
- イベント発生時に Dataverse にアクセスするため、ボタンをクリックした際のイベントなどに適していると思います。
- 登録、更新、削除など一通りが用意されています。
- 使用できるまでの作法や、(データの取得のみなら不要ですが)トークンの取得など手順が少し複雑です。
ローコードツールでやるかはさておき、ゴリゴリ拡張するなら Web API を使うのがよいかと思います。
参考(公式)
余談
React などを使った自由なコンポーネントを追加できるようになったらうれしいなあ。
Discussion