Angular MaterialでSelect要素のOptionを複数行表示にする

掲題の通り。

見た目で言うとこんなん↓↓↓

f:id:kshamoji:20210517194612p:plain
sample

cssのselectorの特定が地味に面倒だったので、同じ様に困った方の一助になれば良いなと思います。

「御託は良いから動くもの見せろ!」って方は以下からどうぞ。

StackBlitz

以下、経緯と解決までの道のり。

要件

Product Owner(以下、PO)「以下のドロップダウンなんですけど...」

f:id:kshamoji:20210517195347p:plain

PO「項目を選択する時に項目名だけじゃなくて、項目の説明も欲しいです。」

私「りょ」

取り敢えず実装してみる

何も考えずにmat-select内を2段にしてみる。

  <mat-form-field style="width: 320px;" appearance="fill">
    <mat-label>Storage</mat-label>
    <mat-select 
      [formControl]="selectedStorage">
      <mat-option>None</mat-option>
      <mat-option *ngFor="let storage of storageList" [value]="storage">
        {{storage.name}}<br>
        {{storage.path}}
      </mat-option>
    </mat-select>
  </mat-form-field>

結果

f:id:kshamoji:20210517200602p:plain

あらら。高さが可変じゃないのね。

selectorを特定...するも効果ナシ

困った時はF12(Developer Mode)。原因のcssを調査。

そして発見。

f:id:kshamoji:20210517201502p:plain

なるほどー。この辺のline-heightを狙い撃ちすればいいのか。

.mat-select-panel .mat-option {
    font-size: inherit;
    line-height: 3em;
    height: 3em;
}
/* 中略 */
.mat-option {
    /* 中略 */
    line-height: 48px; 
    height: 48px;
    /* 中略 */
}

早速cssを更新、、、したけど、効かず。

ビューのカプセル化

調べたところ、Angularには ビューのカプセル化 という仕組みがあり、通常はComponent間でcssの影響を受けないとのこと。(今まで全然気にしてませんでした。すみません。)

AngularではコンポーネントCSSスタイルはコンポーネントのビューにカプセル化され、 アプリケーションの残りの部分には影響しません。

非常に便利な仕組みだが、今は困るなー。

まぁそこはGoogle先生なので、無効化したいシチュエーションも考慮されているらしく、Componentのプロパティに encapsulation: ViewEncapsulation.None を加えると、配下のComponentのビューのカプセル化が解除される。

早速追加する。

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  // Encapsulation has to be disabled in order for the
  // component style to apply to the select panel.
  encapsulation: ViewEncapsulation.None,
})
export class AppComponent {
  title = 'multiline-mat-select';
  /* 中略*/
}

ほんでさっきのcssだと詳細度が元のComponent一緒なので、打ち消せない。

select要素にclassを付与して再チャレンジ。

  <h4>take 3</h4>
  <mat-form-field style="width: 320px;" appearance="fill">
    <mat-label>Storage</mat-label>
    <mat-select 
      panelClass="storage-selector"
      [formControl]="selectedStorage">
      <mat-option>None</mat-option>
      <mat-option *ngFor="let storage of storageList" [value]="storage">
        <b>{{storage.name}}</b><br>
        <small class="drive-path">{{storage.path}}</small>
      </mat-option>
    </mat-select>
  </mat-form-field>
.storage-selector.mat-select-panel {
  .mat-option {
    line-height: 24px;
    height: fit-content;
    min-height: 56px;
    padding-top: 8px;
    padding-bottom: 8px;

    .drive-path {
      color: gray;
    }
  }
}

できたー

f:id:kshamoji:20210517204617p:plain

あとはmat-icon足したりすると最初のキャプチャになります。

まとめ

※独自Directiveを追加するやり方もあるらしいですが、今回はこちらの方法でいこうと思います。

fun :)

結論から申しますと

新卒の頃、報連相時の枕詞として「結論から申しますと」を付けろ、と口を酸っぱくして言われていた話。


企業勤めだったころ、だいたいこの時期になると、研修を終えた新卒の子たちが配属されてきていた。
そんな子達を見て、文系からこの業界に来てボコボコにされた日々を思い出した私は決まってこの話をしていた...気がするので、特に誰に言うわけでもないけれど、日記にまとめてみる。


結論から申せない

1年目の頃の私は、IT業界に順応できず、日々「何が分からないか分からない」といった状態が続いており、作業の手が止まる度にOJT(死語?)担当の先輩社員を呼び止め、やれコンパイルが通らないだの、意図した動きをしないだの、Excelが壊れただのと結構な頻度で節操なく質問していた。

質問しまくる私に、担当の先輩は手を止めて対応してくれていたのだが、その積み重ねが少しづつOJT担当者の進捗に影響していたらしく、見かねたもう一人の先輩(Nさん)がOJT担当を変わると進言した。

Nさんは担当を変わるや否や「私に質問する時は必ず枕詞として『結論から申しますと』を付けてください」と指示しました。
(実際にはネイティブな広島弁によるアウトレイジ感のある言い方でしたが)

そんな指示を受けた私だったが、基本的に三歩歩くと忘れるトラベリング鳥頭のため、その後作業の手が止まると、前担当者と同じノリでNさんに突撃した。

SHAMOJI(以下、S)「すみません、質問よろしいですか?」

Nさん(以下、N)「はい」

S「ここなんですk」

N「。。。結論から申しますと?」

S「あ、、、そうですね、、、結論から申しますと、、、」

_人人人人人人人人人人人人人人_  
> 結論から申せない!!!(^q^) <  
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

。。。結論から申しますと、その当時の私は結論から申せませんでした。

結論から申せなかった理由

当時の私の思考回路としては「手が止まった!」→「助けて先輩!」という、先輩をドラ●もんか何かと勘違いしているような節があり、自身での問題解決を半ば放棄していました。

しかしこの「結論から申しますと」という言葉を強制的に付けられたことにより、私の中に残っていた僅かな論理的思考力が、言葉を紡ぐのを拒否してしまい、フリーズしてしまった。
幽遊白書でいうところの禁句<タブー>みたいな。たぶんそんな感じ。知らんけど。

結論から申すべき理由

N「結論から申せるようなったら、また質問してきてね。」
(注:実際はアウトレイジ語です)

ド●えもぉぉぉぉぉん、、、といった気分にはなりましたが、そこはすぐに気持ちを切り替え、いつもなら「わからん!先輩に相談だ!」としていたところ、質問の内容を15分くらいかけて整理し、再度リベンジに望みました。
すると冒頭で結論を述べたタイミングの、体感5秒くらいで回答が返ってきた後、Nさんからこの取り組みの意図を説明されました。

N「問題が整理されていれば数秒で済むような回答を、整理の時間も含めて周囲の時間を取っていましたよね?」

N「早く仕事をこなそうとする姿勢は立派だけど、残念ながら新人のSHAMOJIの5分と他の先輩たちの5分では価値が違うんだよ。」

N「SHAMOJIと一緒に5分悩むより、SHAMOJIが一人で15分悩んで、先輩達が5秒で応える方が生産性が高いんだ。何なら1時間悩んでも元は取れるよ。」

N「SHAMOJIができる一番の効率化は他の先輩の時間を奪わないことだよ。」

(注:実際はアウトレ(ry )

勿論、そこから全ての質問がスマートにまとめられたワケではないけれど、質問の質は徐々に高められていき、Nさんも「結論から申しますと」を言わなくても(心の中では唱えていたけどw)質問を受け付けてくれるようになった。

まとめと注意と回想と

これは別に新人の質問に対するハードルをあげるためのエピソードではありません。あくまで「(今の自分でできうる限りの)質の高い質問をしよう!」という意図です。
そして私みたいに心臓に毛が生えているような人間相手でもない限り、広島弁で上記のやりとりをするのはやめましょう。

このエピソードを受けて心理的安全性って言葉からは正反対なことを言ってるように感じる人もいるかもしれないけど、「何でも意見や質問が言えるチーム」と「何(も考えん)でも意見や質問が言えるチーム」は違うと思う。

「何(も考えん)でも意見や質問が言えるチーム」ってのは心理的障壁はないかもしれないけど、リスペクトもない気がする。   質問や問題をチームで共有する、ってことは少なからずチームメンバー1人1人の時間を奪う行為だから、今の自分でできる最高の質問・意見に仕上げてから共有して欲しい。

そして受け取る側も、仮に拙い質問や意見であったとしても、相手の立場にたった上でそれが今の相手のベストなのであれば、リスペクトを持って受け止めよう。

今は会社として新卒とか取れる状態にないけど、この話は定期的にしていきたい。  

。。。そういえばNさん元気かな。
私が会社を辞めた時、「俺が厳しくし過ぎたせいかな」と気にしていたみたいだけど、そんなことはないですよ。
10年近くたった今も私の脳内にアウトレイジ系テストエンジニアとして居着いてて、たまに「お前のEnterキーは軽すぎる」と怒っておられます笑

いつかまたどこかでお会いできたらいいな。

fun :)

「Qiita × Uzabase Tech Meetup#1 〜 TDDカルチャーの未来」 を視聴しました

Qiita × Uzabase Tech Meetup#1 - connpass」 を視聴したので、感想をつらつらと。

企業にテスト文化を根付かせる戦略

お目当ての講演。内容もそうだけど単純にプレゼンも上手かった。淀みなく聞き入ってしまった。

4つのキーメトリクス

これからの時代に求められる開発のメトリクスとして、以下の4つを説明してた。

  1. リードタイム
    • コードが書かれてからリリースされるまでの時間。
  2. デプロイ頻度
    • デプロイされる頻度。(週1回とか)
  3. MTTR(Mean Time To Repair, 平均修復時間)
    • バグが発生してから修復が完了するまでの時間の平均値。
    • 従来はMTBF(Mean Time Between Failure、平均故障時間、ソフトウェアの場合はバグの個数)が用いられていた
  4. 変更失敗率

「リードタイム」と「デプロイ頻度」がスピードを表す指標。
MTTR」と「変更失敗率」が品質を表す指標。

MTTRとかMTBFってハードウェアの指標かと思ってたけど、ソフトウェアにも使うのね。
ソフトウェアのバグってユーザ影響の低いバグだと放置されがちだから、レガシーなソフトウェアだととんでもない値になりそう。
実際、昔関わっていたプロジェクトだと10年間くらい放置してバグとかあったし。。。

そして実際に測定した結果が以下らしい。(2019年の調査)

エリート ハイパフォーマー ミディアム
パフォーマー
ローパフォーマー
リードタイム 1日未満 1日から1週間 1週間から1ヶ月 1ヶ月から6ヶ月
デプロイ頻度 オンデマンド
(1日複数回)
1日1回から週1回 週1回から月1回 1ヶ月から6ヶ月
MTTR 1時間未満 1日未満 1日未満 1週間から1ヶ月
変更失敗率 0 - 15% 0 - 15% 0 - 15% 46 - 60%

リードタイム毎に組織を分類した結果のメトリクスみたい。

講演でも言ってたけど、開発速度(リードタイム、デプロイ頻度)と品質(MTTR、変更失敗率)はトレードオフの関係ではない、ってとこが面白いな。
(単にスーパープログラマを沢山抱えている組織は開発スピードも早くて品質も良いだけでは?。。。みたいな身も蓋もないことは言わない)

私が以前所属していた組織はまさに「ローパフォーマー」に属するところで、それはSIerでクライアントの了承無しにはデプロイできないから、という言い訳があるものの、結果的にバグは多かったし、リリースの度に緊張感もあった。
Sales Naviでは「ハイパフォーマー」を目標にCI/CD、DevOpsへ投資していきたいな。
バックエンド(Java)側のユニットテストは順調に記述できてるんだけど、フロントエンド(Angular)のユニットテストは全然できていない。猛省。。。

テストを書く時間がない

これはよく聞く話。
「テスト書く時間がない」のではなく「テスト書かないから時間がない」ってやつ。
よく聞く話といいつつ、やってしまいがち。耳が痛い。。。

テストにコストがかかることの解決方法は、テストをやめることではありません。
うまくなることです。 Sandi Metz

はい。おっしゃる通りです。。。

テストは品質をあげない

講演の最後、とても印象深かった。

  • テストは品質をあげない
    • 品質が「わかる」ようになる
    • わかることこそ大事
  • テストを書くだけでは良くはならない
    • 体重計に乗るだけでは痩せない
  • 品質を上げるのは設計とプログラミング
  • 再設計とリファクタリングをテストで支える

CSM研修での「Scrumは問題解決のフレームワークではありません。現状を把握するフレームワークです。」ってのを思い出した。

E2Eの過去・現在・未来

E2Eテスト難しいよね。課題あるよね、って話とSeleniumとかのテストツールの話。
Googleでは全て(UI含む)自動テストしてる、ってとこでマジか!かっけぇ!ってなった。

和田さんの講演と比べて内容が薄くなったのに他意はありません。トイレ行ってただけです。

TDD実践を経て変わったこと

UZABASEのエンジニアさん達がTDDの実践を経てのBefore、Afterを語ってた。

印象的だったのは「テストを先に書くことで作るものが明確になる」ってとこ。

前職ではTDDの実現はできなかったけど、苦し紛れにマニュアルテストで使うテスト仕様書を先に書く、ってのはやってみた。
それだけでも驚くほど品質が上がったし、実践したメンバーも同じ感想を述べていた。

要求仕様だけを元にコーディングを始めるのと、テスト仕様書を書いてからコーディングを始めるのとでは見える景色が違う。

私のいたプロジェクトもそうだったけど、ユニットテストを書きたくても(フレームワーク都合、組織側のDevOpsに対する理解などにより)書けない、っていう状況は確かにある。
ならばせめて後回しにしていたテスト仕様書を先に書くだけでも作業の質が全然変わるから是非やってみて欲しい。

まとめ

TDDへの理解が浅かったな、って反省した。
ちゃんと本読んで勉強しよ、そんで実践しよ、とも思えた。

ユニットテスト書いてりゃ良いんでしょ、ってならないよう気をつけよ。

Fun :)

お笑い芸人に学ぶ 例え話の上手い人

とあるトーク番組で繰り広げられた一幕を受けて、例え話上手いなーって感じる人と、よく分からん例え話だなーって感じる人の違いを考察してみた。

きっかけとなったやりとり

「日常の些細な出来事から社会問題に至るまでを本音トークでぶった斬る」という趣旨のバラエティで、その回ではある女芸人さんが女優さんの扱いに対して不満を述べており、司会の芸人さんが「それは仕方ない、なぜなら...」と反駁する下りが面白かった。

簡単に説明すると以下の通り。

女芸人: 女優さんが全く似ていないクレヨンしんちゃんのモノマネをして「可愛い」というリアクションを頂くことに違和感がある。
モノマネをした結果は「似てる」「似てない」であり、「可愛い」「可愛くない」といるリアクションはおかしい。

司会:僕は女優さんであってもモノマネが似てなかったら「似てない」って言う。

女芸人:それは素晴らしい!

司会:でも「可愛い」とも言う。

女芸人:なんでですか!?

司会: 例えば3mの大男が全く似ていないクレヨンしんちゃんのモノマネをしたとしたら、「似てない、でもデカイ」ってなるやろ?

女芸人: なりますね。

司会: めちゃくちゃ口の臭いやつが全く似てないクレヨンしんちゃんのモノマネをしたとしても、「似てない、でも口臭い」ってなるやろ?

女芸人: 。。。デリカシーは置いといて、なりますね。

司会:じゃあ可愛い女優さんが全く似てないクレヨンしんちゃんのモノマネをしたとしたら、「似てない、でも可愛い」ってなるやろ?

女芸人:。。。すみませんでした m( )m

(笑)

例え話の本質

上記を踏まえて、例え話の本質は「汎化」と「特化」を繰り返す行為なんだな、と改めて思った。

つまり前述の話者は以下を高速で行っているんだろうな。

可愛い女優さんが行った似ていないモノマネに対して「似てない、でも可愛い」とコメントをする

↓ 汎化(generalization)

ある特徴(X)をもつ個人が行った似ていないモノマネに対して「似てない、でもX」とコメントする

↓ 特化(specialization)

ある特徴(デカイ)をもつ3mの大男が行った似ていないモノマネに対して「似てない、でもデカイ」とコメントする

これは単純な例だけど、もっと複雑な例え話をその場で上手くやる人は、もっと複雑な汎化→特化を脳内で繰り返しているんだろうな。

さらに言えばトークしているメンバーや客層に合わせて適切な特化をしているんだろうな。
それには豊富なドメイン知識が求められるんだろうな。

つまり例え話の上手い人はきっとDDDに向いているんだろうなー。

まとめ

例え話上手い人 = 物事の汎化<->特化に長けた人、ってことで納得した。

採用の時、何か例え話をしてもらうとある程度プログラマ適正が見れるかもしれない。

早速試してみようかな。応募者ゼロだけど。。。泣

Fun :)

「チームビルディングが得意」って言う人が苦手

自分の感情論を深掘りするのって面白いよね。

今回は嬉々として「チームビルディングが得意です!!!」って言い切る人がなんとなく苦手だな、って思う気持ちをまじめに考えてみた。

そもそも「チームビルディング」ってなんだっけ?

Team building is a collective term for various types of activities used to enhance social relations and define roles within teams, often involving collaborative tasks. Team building - Wikipedia

「define roles within teams(チーム内の役割の定義)」と「enhance social relations(社会的関係の強化)」をするための諸々の活動なのね。
具体的にどんな活動がのことなんだろう。続きも読む。

The formal definition of team-building includes:

  • aligning around goals
  • building effective working relationships
  • reducing team members' role ambiguity
  • finding solutions to team problems

Team building - Wikipedia

(which? って怒られてるけど)一般的には以下の4つが定義として含まれるらしい。

  • 目標に合わせて調整すること
  • 効果的な仕事上の関係を構築すること
  • チームメンバーの役割のあいまいさを減らすこと
  • チームの問題の解決策を見つけること

主語が抜けているけど、チーム外の人間が行うチームマネジメントの一貫として行う活動というよりは、チームメンバーの一人一人がチームのために行う活動を指すんだろうな。
そうなるとなんかScrumっぽいな。というかScrumだな。

「チームビルディングが得意」という単語への違和感

Excelできます!」「Javaできます!」というワードに対する違和感と一緒な気がする。

全体像があまりにも大きい能力について、受け手側の誤解を考慮せずに(誤解が生まれることを知らずに)自身の能力を伝えてしまっている状態。
ダニング=クルーガー効果で出てくる曲線の「完全に理解した」の領域にいる人から発せられる言葉、だと受け取ってしまうんだろうな。

なんか「バイトリーダーやってました!」って言いそうな人が使ってるイメージがある(偏見)

結論

本当にチームビルディングに関わってきた人間なら安易にその言葉を一括りにして「得意」だなんて言わない(言えない)であろうという独断と偏見の元、「チームビルディング得意勢」に苦手意識を持っていたんだなぁ、と納得した。
逆にチームビルディングしんどい(でも楽しい)勢の人たちの話が楽しく感じるのはきっと正しく内省できている人たちの心の有様がとても勉強になるからなんだろうな、とも思った。

これからはチームビルディングのCapabilityについて、この言葉を言ってくれる人を信じます。

「ワタシハ チームビルディング チョットデキル」

Fun :)