Merge pull request #391 from shikorism/tsf

全フロントエンドコードのTypeScript化
This commit is contained in:
Hinaloe 2020-06-06 17:03:03 +09:00 committed by GitHub
commit d3592f9fea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 117 additions and 58 deletions

View File

@ -11,7 +11,11 @@
"stylelint": "stylelint resources/assets/sass/**/*" "stylelint": "stylelint resources/assets/sass/**/*"
}, },
"devDependencies": { "devDependencies": {
"@types/bootstrap": "^4.5.0",
"@types/cal-heatmap": "^3.3.10",
"@types/chart.js": "^2.7.1",
"@types/jquery": "^3.3.38", "@types/jquery": "^3.3.38",
"@types/js-cookie": "^2.2.0",
"bootstrap": "^4.5.0", "bootstrap": "^4.5.0",
"cal-heatmap": "^3.3.10", "cal-heatmap": "^3.3.10",
"chart.js": "^2.7.1", "chart.js": "^2.7.1",

View File

@ -0,0 +1,4 @@
// なんか @types/cal-heatmap 入れても動かなかったんですけど!!
declare module 'cal-heatmap' {
export = CalHeatMap;
}

View File

@ -0,0 +1,4 @@
// @types/bootstrap に足りないもの
interface JQuery<TElement = HTMLElement> {
modal(action: "toggle" | "show" | "hide" | "handleUpdate" | "dispose", relatedTarget?: TElement): this;
}

View File

@ -0,0 +1,12 @@
// tissue.ts で定義されているjQuery Pluginの型定義
declare namespace JQueryTissue {
interface LinkCardOptions {
endpoint: string;
}
}
interface JQuery<TElement = HTMLElement> {
linkCard: (options?: JQueryTissue.LinkCardOptions) => this;
pageSelector: () => this;
deleteCheckinModal: () => this;
}

View File

@ -1,4 +1,5 @@
import Cookies from 'js-cookie'; import * as Cookies from 'js-cookie';
import jqXHR = JQuery.jqXHR;
require('./bootstrap'); require('./bootstrap');
@ -40,7 +41,7 @@ $(() => {
const isLiked = $this.data('liked'); const isLiked = $this.data('liked');
if (isLiked) { if (isLiked) {
const callback = (data) => { const callback = (data: any) => {
$this.data('liked', false); $this.data('liked', false);
$this.find('.oi-heart').removeClass('text-danger'); $this.find('.oi-heart').removeClass('text-danger');
@ -54,7 +55,7 @@ $(() => {
type: 'json' type: 'json'
}) })
.then(callback) .then(callback)
.catch(function (xhr) { .catch(function (xhr: jqXHR) {
if (xhr.status === 404) { if (xhr.status === 404) {
callback(JSON.parse(xhr.responseText)); callback(JSON.parse(xhr.responseText));
return; return;
@ -64,7 +65,7 @@ $(() => {
alert('いいねを解除できませんでした。'); alert('いいねを解除できませんでした。');
}); });
} else { } else {
const callback = (data) => { const callback = (data: any) => {
$this.data('liked', true); $this.data('liked', true);
$this.find('.oi-heart').addClass('text-danger'); $this.find('.oi-heart').addClass('text-danger');
@ -81,7 +82,7 @@ $(() => {
} }
}) })
.then(callback) .then(callback)
.catch(function (xhr) { .catch(function (xhr: jqXHR) {
if (xhr.status === 409) { if (xhr.status === 409) {
callback(JSON.parse(xhr.responseText)); callback(JSON.parse(xhr.responseText));
return; return;

View File

@ -2,16 +2,16 @@
import './tissue'; import './tissue';
// Setup global request header // Setup global request header
const token = document.head.querySelector('meta[name="csrf-token"]'); const token = document.head.querySelector<HTMLMetaElement>('meta[name="csrf-token"]');
if (!token) { if (!token) {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token'); console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
} else {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': token.content
}
});
} }
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': token.content
}
});
// Bootstrap // Bootstrap
import 'bootstrap'; import 'bootstrap';

View File

@ -1,10 +1,10 @@
import Chart from 'chart.js'; import * as Chart from 'chart.js';
const graph = document.getElementById('global-count-graph'); const graph = document.getElementById('global-count-graph') as HTMLCanvasElement;
const labels = JSON.parse(document.getElementById('global-count-labels').textContent); const labels = JSON.parse(document.getElementById('global-count-labels')!.textContent as string);
const data = JSON.parse(document.getElementById('global-count-data').textContent); const data = JSON.parse(document.getElementById('global-count-data')!.textContent as string);
new Chart(graph.getContext('2d'), { new Chart(graph.getContext('2d')!, {
type: 'bar', type: 'bar',
data: { data: {
labels, labels,

View File

@ -1,12 +1,12 @@
(function ($) { (function ($) {
$.fn.linkCard = function (options) { $.fn.linkCard = function (options) {
var settings = $.extend({ const settings = $.extend({
endpoint: '/api/checkin/card' endpoint: '/api/checkin/card'
}, options); }, options);
return this.each(function () { return this.each(function () {
var $this = $(this); const $this = $(this);
$.ajax({ $.ajax({
url: settings.endpoint, url: settings.endpoint,
method: 'get', method: 'get',
@ -15,11 +15,11 @@
url: $this.find('a').attr('href') url: $this.find('a').attr('href')
} }
}).then(function (data) { }).then(function (data) {
var $metaColumn = $this.find('.col-12:last-of-type'); const $metaColumn = $this.find('.col-12:last-of-type');
var $imageColumn = $this.find('.col-12:first-of-type'); const $imageColumn = $this.find('.col-12:first-of-type');
var $title = $this.find('.card-title'); const $title = $this.find('.card-title');
var $desc = $this.find('.card-text'); const $desc = $this.find('.card-text');
var $image = $imageColumn.find('img'); const $image = $imageColumn.find('img');
if (data.title === '') { if (data.title === '') {
$title.hide(); $title.hide();
@ -56,17 +56,17 @@
$.fn.deleteCheckinModal = function () { $.fn.deleteCheckinModal = function () {
return this.each(function () { return this.each(function () {
$(this).on('show.bs.modal', function (event) { $(this).on('show.bs.modal', function (event) {
var target = $(event.relatedTarget); const target = $(event.relatedTarget!);
var modal = $(this); const modal = $(this);
modal.find('.modal-body .date-label').text(target.data('date')); modal.find('.modal-body .date-label').text(target.data('date'));
modal.data('id', target.data('id')); modal.data('id', target.data('id'));
}).find('.btn-danger').on('click', function (event) { }).find('.btn-danger').on('click', function (event) {
var modal = $('#deleteCheckinModal'); const modal = $('#deleteCheckinModal');
var form = modal.find('form'); const form = modal.find('form');
form.attr('action', form.attr('action').replace('@', modal.data('id'))); form.attr('action', form.attr('action')?.replace('@', modal.data('id')) || null);
form.submit(); form.submit();
}) })
}); });
}; };
})(jQuery); })(jQuery);

View File

@ -1,4 +1,5 @@
import CalHeatMap from 'cal-heatmap'; import * as CalHeatMap from 'cal-heatmap';
import {subMonths} from 'date-fns';
if (document.getElementById('cal-heatmap')) { if (document.getElementById('cal-heatmap')) {
new CalHeatMap().init({ new CalHeatMap().init({
@ -7,9 +8,9 @@ if (document.getElementById('cal-heatmap')) {
subDomain: 'day', subDomain: 'day',
domainLabelFormat: '%Y/%m', domainLabelFormat: '%Y/%m',
weekStartOnMonday: false, weekStartOnMonday: false,
start: new Date().setMonth(new Date().getMonth() - 9), start: subMonths(new Date(), 9),
range: 10, range: 10,
data: JSON.parse(document.getElementById('count-by-day').textContent), data: JSON.parse(document.getElementById('count-by-day')!.textContent as string),
legend: [1, 2, 3, 4] legend: [1, 2, 3, 4]
}); });
} }

View File

@ -1,12 +1,12 @@
import CalHeatMap from 'cal-heatmap'; import * as CalHeatMap from 'cal-heatmap';
import Chart from 'chart.js'; import * as Chart from 'chart.js';
import {addMonths, format} from 'date-fns'; import {addMonths, format} from 'date-fns';
const graphData = JSON.parse(document.getElementById('graph-data').textContent); const graphData = JSON.parse(document.getElementById('graph-data')!.textContent as string);
function createLineGraph(id, labels, data) { function createLineGraph(id: string, labels: string[], data: any) {
const context = document.getElementById(id).getContext('2d'); const context = (document.getElementById(id) as HTMLCanvasElement).getContext('2d');
return new Chart(context, { return new Chart(context!, {
type: 'line', type: 'line',
data: { data: {
labels: labels, labels: labels,
@ -41,9 +41,9 @@ function createLineGraph(id, labels, data) {
}); });
} }
function createBarGraph(id, labels, data) { function createBarGraph(id: string, labels: string[], data: any) {
const context = document.getElementById(id).getContext('2d'); const context = (document.getElementById(id) as HTMLCanvasElement).getContext('2d');
new Chart(context, { new Chart(context!, {
type: 'bar', type: 'bar',
data: { data: {
labels: labels, labels: labels,
@ -73,10 +73,7 @@ function createBarGraph(id, labels, data) {
}); });
} }
/** function createMonthlyGraphData(from: Date) {
* @param {Date} from
*/
function createMonthlyGraphData(from) {
const keys = []; const keys = [];
const values = []; const values = [];
@ -90,9 +87,13 @@ function createMonthlyGraphData(from) {
return {keys, values}; return {keys, values};
} }
function getCurrentYear() { function getCurrentYear(): number {
const year = location.pathname.split('/').pop(); const year = location.pathname.split('/').pop() || '';
return /^(20[0-9]{2})$/.test(year) ? year : null; if (/^(20[0-9]{2})$/.test(year)) {
return parseInt(year, 10);
} else {
throw 'Invalid year';
}
} }
if (document.getElementById('cal-heatmap')) { if (document.getElementById('cal-heatmap')) {

14
webpack.mix.js vendored
View File

@ -12,13 +12,13 @@ require('laravel-mix-bundle-analyzer')
| |
*/ */
mix.js('resources/assets/js/app.js', 'public/js') mix.ts('resources/assets/js/app.ts', 'public/js')
.js('resources/assets/js/home.js', 'public/js') .ts('resources/assets/js/home.ts', 'public/js')
.js('resources/assets/js/user/profile.js', 'public/js/user') .ts('resources/assets/js/user/profile.ts', 'public/js/user')
.js('resources/assets/js/user/stats.js', 'public/js/user') .ts('resources/assets/js/user/stats.ts', 'public/js/user')
.js('resources/assets/js/setting/privacy.js', 'public/js/setting') .ts('resources/assets/js/setting/privacy.ts', 'public/js/setting')
.js('resources/assets/js/setting/import.js', 'public/js/setting') .ts('resources/assets/js/setting/import.ts', 'public/js/setting')
.js('resources/assets/js/setting/deactivate.js', 'public/js/setting') .ts('resources/assets/js/setting/deactivate.ts', 'public/js/setting')
.ts('resources/assets/js/checkin.ts', 'public/js') .ts('resources/assets/js/checkin.ts', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css') .sass('resources/assets/sass/app.scss', 'public/css')
.autoload({ .autoload({

View File

@ -745,6 +745,33 @@
dependencies: dependencies:
any-observable "^0.3.0" any-observable "^0.3.0"
"@types/bootstrap@^4.5.0":
version "4.5.0"
resolved "https://registry.yarnpkg.com/@types/bootstrap/-/bootstrap-4.5.0.tgz#07a079d3ee2b1646491082d6162048d7bf4610b5"
integrity sha512-AWu7D+Cduyic75YptSRiXuCIy1c3SsmYk/9ixS68Ft2eAgg2wRj5U2M+7PK5zpakk4gTgfrWHeGxJqkSjttwyQ==
dependencies:
"@types/jquery" "*"
popper.js "^1.14.1"
"@types/cal-heatmap@^3.3.10":
version "3.5.35"
resolved "https://registry.yarnpkg.com/@types/cal-heatmap/-/cal-heatmap-3.5.35.tgz#ca66c42bef97b6ba4103fdcda9a381300f9929e3"
integrity sha512-QG6NfOPphdo58oNHZ6JXCwQ4KgC94OeUAdo+KNrkbMzA+4FkrlXD1BnxvncOsOfSiJiiaQwxdVoE/AXMin39vw==
dependencies:
"@types/d3" "^3"
"@types/chart.js@^2.7.1":
version "2.9.21"
resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.21.tgz#ecb85f1aac2d7b28310df8cc9c88b6b5db1b91bd"
integrity sha512-bjwdC+SvE/c3rHYYcX8UbRmTvjEUP9Dhuk/iWXygH6EFDYf4OcofnwxBpJx+A4qU3YBr54a7wtPdswfg9Yt3rg==
dependencies:
moment "^2.10.2"
"@types/d3@^3":
version "3.5.43"
resolved "https://registry.yarnpkg.com/@types/d3/-/d3-3.5.43.tgz#e9b4992817e0b6c5efaa7d6e5bb2cee4d73eab58"
integrity sha512-t9ZmXOcpVxywRw86YtIC54g7M9puRh8hFedRvVfHKf5YyOP6pSxA0TvpXpfseXSCInoW4P7bggTrSDiUOs4g5w==
"@types/events@*": "@types/events@*":
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
@ -759,13 +786,18 @@
"@types/minimatch" "*" "@types/minimatch" "*"
"@types/node" "*" "@types/node" "*"
"@types/jquery@^3.3.38": "@types/jquery@*", "@types/jquery@^3.3.38":
version "3.3.38" version "3.3.38"
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.38.tgz#6385f1e1b30bd2bff55ae8ee75ea42a999cc3608" resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.38.tgz#6385f1e1b30bd2bff55ae8ee75ea42a999cc3608"
integrity sha512-nkDvmx7x/6kDM5guu/YpXkGZ/Xj/IwGiLDdKM99YA5Vag7pjGyTJ8BNUh/6hxEn/sEu5DKtyRgnONJ7EmOoKrA== integrity sha512-nkDvmx7x/6kDM5guu/YpXkGZ/Xj/IwGiLDdKM99YA5Vag7pjGyTJ8BNUh/6hxEn/sEu5DKtyRgnONJ7EmOoKrA==
dependencies: dependencies:
"@types/sizzle" "*" "@types/sizzle" "*"
"@types/js-cookie@^2.2.0":
version "2.2.6"
resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f"
integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw==
"@types/minimatch@*": "@types/minimatch@*":
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@ -5627,7 +5659,7 @@ please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1:
dependencies: dependencies:
semver-compare "^1.0.0" semver-compare "^1.0.0"
popper.js@^1.14.7: popper.js@^1.14.1, popper.js@^1.14.7:
version "1.16.1" version "1.16.1"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==