diff --git a/src/0,1歳用日誌/main.mobile.js b/src/0,1歳用日誌/main.mobile.js new file mode 100644 index 0000000..c7df799 --- /dev/null +++ b/src/0,1歳用日誌/main.mobile.js @@ -0,0 +1,6 @@ +(function () { + "use strict"; + + addApproveFlowAction(true); + +})(); \ No newline at end of file diff --git a/src/2歳以上日誌/main.mobile.js b/src/2歳以上日誌/main.mobile.js new file mode 100644 index 0000000..c7df799 --- /dev/null +++ b/src/2歳以上日誌/main.mobile.js @@ -0,0 +1,6 @@ +(function () { + "use strict"; + + addApproveFlowAction(true); + +})(); \ No newline at end of file diff --git a/src/main.mobile.css b/src/main.mobile.css new file mode 100644 index 0000000..0b29941 --- /dev/null +++ b/src/main.mobile.css @@ -0,0 +1,95 @@ +.btn-group-area { + display: flex; + /* margin-left: 2.5em; */ + align-items: flex-end; +} +.btn-group-area .label { + margin: 0 4px; +} + +.btn-group-area .input { + padding-left: 8px; +} + +.btn-group-area .year { + --kuc-text-input-width: calc(4em + 16px); + --kuc-text-input-height: 48px; +} +.btn-group-area .year input { + text-align: center; +} + +.btn-group-area .month, +.btn-group-area .date, +.btn-group-area .classroom { + --kuc-combobox-toggle-width: calc(2em + 16px); + --kuc-combobox-toggle-height: 48px; +} + +.btn-group-area .classroom { + --kuc-combobox-toggle-width: calc(3em + 16px); +} + +.btn-group-area .month input[class^='kuc-combobox'], +.btn-group-area .date input[class^='kuc-combobox'], +.btn-group-area .classroom input[class^='kuc-combobox'] { + text-align: center; + padding-right: 8px; +} +.btn-group-area .month input + div[class$="icon"], +.btn-group-area .date input + div[class$="icon"], +.btn-group-area .classroom input + div[class$="icon"] { + display: none; +} + +.action-btn { + margin: 0 8px; +} + +.customized-record-header-space { + padding-top: 16px; + padding-left: 8px; +} +.customized-record-header-space > .btn-group-area { + padding: 0; + margin: 0; +} +.kintone-app-headermenu-space { + height: auto; + display: inline-flex; +} + +#user-js-header-clocking-btn-area { + margin: 4px 0; + text-align: center; +} + +#user-js-header-clocking-btn-area > .action-btn { + --kuc-button-width: 6em +} + +#user-js-header-clocking-btn-area > .action-btn:first-child { + margin-right: 1em; +} + +#user-js-clock-in-btn-area > .action-btn, +#user-js-clock-out-btn-area > .action-btn { + --kuc-mobile-button-height: 35px; + margin: .5em 12px; +} + +.kuc--has-spinner { + position: relative; +} +div[class^='kuc-spinner'][class$='__spinner'] { + margin-top: 89px; + height: calc(100% - 89px); + position: absolute; + --kuc-spinner-text-color: #3498db; + --kuc-spinner-loader-color: #3498db; +} +div[class^='kuc-spinner'][class$='mask'] { + top: 89px; + position: absolute; + background-color: white; +} diff --git a/src/utils-mobile.js b/src/utils-mobile.js new file mode 100644 index 0000000..d2595b3 --- /dev/null +++ b/src/utils-mobile.js @@ -0,0 +1,190 @@ +const Kuc = Kucs['1.19.0']; + +let notificationEl; +function getHeaderSpace(className, isDetailPage) { + const headerSpace = kintone.mobile.app.getHeaderSpaceElement(); + if (!headerSpace) { + throw new Error('このページではヘッダー要素が利用できません。'); + }; + + const _className = isDetailPage ? 'customized-record-header-space' : 'customized-header-space'; + + headerSpace.className += (' ' + _className + ' ' + className); + headerSpace.parentElement.className += (' ' + _className + '-wrapper ' + className); + + return headerSpace; +} + + +function createBtnGroupArea(groupId, btnLabel, btnOnClick, { btnElId = false, yearElId = false, monthElId = false, dateElId = false, classElId = false, defaultThisMonth = false, }) { + const result = {}; + + if (document.getElementById(groupId)) { + return; + } + + const btnGroupAreaEl = document.createElement('div'); + btnGroupAreaEl.id = groupId; + btnGroupAreaEl.className = 'btn-group-area' + result[groupId] = btnGroupAreaEl; + + if (yearElId) { + const yearEl = new Kuc.MobileText({ + value: "" + new Date().getFullYear(), + id: yearElId, + label: '年', + className: 'year input' + }); + result[yearElId] = yearEl; + btnGroupAreaEl.appendChild(yearEl); + } + + if (monthElId) { + const monthEl = new Kuc.MobileDropdown({ + value: defaultThisMonth ? monthItems[new Date().getMonth()].value : undefined, + id: monthElId, + className: 'month input', + label: '月', + items: monthItems, + }); + result[monthElId] = monthEl; + btnGroupAreaEl.appendChild(monthEl); + } + + if (dateElId) { + const dateEl = new Kuc.MobileDropdown({ + value: dateItems[new Date().getDate() - 1].value, + id: dateElId, + items: dateItems, + label: '日', + className: "date input", + }); + result[dateElId] = dateEl; + btnGroupAreaEl.appendChild(dateEl); + } + + if (classElId) { + + const classEl = new Kuc.MobileDropdown({ + id: classElId, + items: classItems, + className: "classroom input", + label: 'クラス', + }); + result[classElId] = classEl; + btnGroupAreaEl.appendChild(classEl); + } + + const btnEl = new Kuc.MobileButton({ + text: btnLabel, + type: "submit", + className: "action-btn", + id: btnElId, + }); + result[btnElId] = btnEl; + btnEl.addEventListener('click', (e) => { + showError(false); + const checkResult = checkInputData(result, { btnLabel, yearElId, monthElId, dateElId, classElId }); + if (checkResult) { + btnOnClick(e, checkResult); + } + }); + btnGroupAreaEl.appendChild(btnEl); + + return result; +} + +function checkInputData(map, { btnLabel, yearElId, monthElId, dateElId, classElId }) { + const year = yearElId && map[yearElId].value; + const month = monthElId && map[monthElId].value; + const date = dateElId && (map[dateElId].value === 'end' ? getLastDate(year, month).getDate() : map[dateElId].value); + const className = classElId && map[classElId].value; + + const errorMsgs = []; + + if (yearElId) { + const yearRegex = /^\d+$/; + if (!yearRegex.test(year)) { + errorMsgs.push(' · 年は整数で入力してください。'); + } + } + if (monthElId && !month) { + errorMsgs.push(' · 月を選択してください。'); + } + if (dateElId && !date) { + errorMsgs.push(' · 日を選択してください。'); + } + if (classElId && !className) { + errorMsgs.push(' · クラスを選択してください。'); + } + if (errorMsgs.length > 0) { + showError(true, btnLabel + 'エラー\n' + errorMsgs.join('\n')) + return; + } + + return { + year, + month, + date, + className, + } +} + +function createBtn(id, label, onClick) { + const btnEl = new Kuc.MobileButton({ + text: label, + type: "submit", + className: "action-btn", + id, + }); + btnEl.addEventListener('click', onClick); + return btnEl; +} + +function hideSpaceField(ids) { + ids.forEach(id => { + const area = kintone.mobile.app.record.getSpaceElement(id); + area.parentElement.style.minWidth = '0'; + area.parentElement.style.display = 'none'; + }); +} + +const statusFieldMap = { + '指導教諭確認中': '担任', + '主幹確認中': '指導', + '園長確認中': '主幹', + '完了': '園長' +} + +function addApproveFlowAction() { + return kintone.events.on("mobile.app.record.detail.process.proceed", (event) => { + const field = statusFieldMap[event.nextStatus.value]; + if (field) { + event.record[field].value = kintone.getLoginUser().name; + } + return event; + }); +} + +function showError(show, text) { + if (show) { + buildNotification('danger', text); + notificationEl.open(); + console.error(text); + } else { + notificationEl && notificationEl.close(); + } +} + +function buildNotification(type, text, duration = -1) { + const param = { + type, + text, + duration + } + if (!notificationEl) { + notificationEl = new Kuc.MobileNotification(param); + } else { + Object.assign(notificationEl, param); + } +} diff --git a/src/utils.js b/src/utils.js index 4cf7f2f..a996166 100644 --- a/src/utils.js +++ b/src/utils.js @@ -512,8 +512,8 @@ function addApproveFlowAction() { return kintone.events.on("app.record.detail.process.proceed", (event) => { const field = statusFieldMap[event.nextStatus.value]; if (field) { - event.record[field].value = kintone.getLoginUser().name; + event.record[field].value = kintone.getLoginUser().name; } return event; - }); +}); } \ No newline at end of file diff --git a/src/個別配慮/main.mobile.js b/src/個別配慮/main.mobile.js new file mode 100644 index 0000000..c7df799 --- /dev/null +++ b/src/個別配慮/main.mobile.js @@ -0,0 +1,6 @@ +(function () { + "use strict"; + + addApproveFlowAction(true); + +})(); \ No newline at end of file diff --git a/src/園児別出欠簿入力/clock-btn-desktop-mobile.js b/src/園児別出欠簿入力/clock-btn-desktop-mobile.js new file mode 100644 index 0000000..121634c --- /dev/null +++ b/src/園児別出欠簿入力/clock-btn-desktop-mobile.js @@ -0,0 +1,57 @@ + +(function () { + "use strict"; + + // ------------------- 詳細画面表示時の処理 ------------------- + kintone.events.on('mobile.app.record.detail.show', function (event) { + const area = kintone.mobile.app.record.getSpaceElement('header-clocking-btn-area'); + + const clockIn = createBtn('clock-in', '登園', dateToFieldInDetail('登園時刻')); + const clockOut = createBtn('clock-out', '帰園', dateToFieldInDetail('帰園時刻')); + area.appendChild(clockIn); + area.appendChild(clockOut); + + hideSpaceField(['clock-in-btn-area', 'clock-out-btn-area']); + return event; + }); + + function dateToFieldInDetail(fieldCode) { + return async function (e) { + await new KintoneRestAPIClient().record.updateRecord({ + app: kintone.mobile.app.getId(), + id: kintone.mobile.app.record.getId(), + record: { + [fieldCode]: { + value: getCurrentTime() + } + } + }); + location.reload(); + } + } + + + // ------------------- 編集画面表示時の処理 ------------------- + kintone.events.on(['mobile.app.record.create.show', 'mobile.app.record.edit.show'], function (event) { + const clockIn = createBtn('clock-in', '登園', dateToFieldInEdit('登園時刻')); + kintone.mobile.app.record.getSpaceElement('clock-in-btn-area').appendChild(clockIn); + const clockOut = createBtn('clock-out', '帰園', dateToFieldInEdit('帰園時刻')); + kintone.mobile.app.record.getSpaceElement('clock-out-btn-area').appendChild(clockOut); + return event; + }); + + function dateToFieldInEdit(fieldCode) { + return function (e) { + var record = kintone.mobile.app.record.get(); + record['record'][fieldCode]['value'] = getCurrentTime(); + kintone.mobile.app.record.set(record); + } + } + + function getCurrentTime() { + const now = new Date(); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + return `${hours}:${minutes}`; + } +})(); \ No newline at end of file diff --git a/src/園児別出欠簿入力/main.js b/src/園児別出欠簿入力/main.js index a06cc62..4de89d2 100644 --- a/src/園児別出欠簿入力/main.js +++ b/src/園児別出欠簿入力/main.js @@ -3,7 +3,7 @@ const APP_ENV = env["園児別出欠簿入力"]; addApproveFlowAction(); - + kintone.events.on("app.record.index.show", (event) => { const headerSpace = getHeaderSpace('single-label-line'); diff --git a/src/園児別出欠簿入力/main.mobile.js b/src/園児別出欠簿入力/main.mobile.js new file mode 100644 index 0000000..b87a305 --- /dev/null +++ b/src/園児別出欠簿入力/main.mobile.js @@ -0,0 +1,21 @@ +(function () { + "use strict"; + + addApproveFlowAction(true); + + kintone.events.on("mobile.app.record.index.show", (event) => { + const headerSpace = getHeaderSpace('single-label-line'); + + // if (event.viewId === APP_ENV.view.linkFor0to1) { + // Link1Handler.getInstance(headerSpace); + // return event; + // } + + // if (event.viewId === APP_ENV.view.linkForOthers) { + // Link2Handler.getInstance(headerSpace); + // return event; + // } + + // BatchCreateHandler.getInstance(headerSpace); + }); +})(); \ No newline at end of file diff --git a/src/園児台帳/main.mobile.js b/src/園児台帳/main.mobile.js new file mode 100644 index 0000000..2d0eaff --- /dev/null +++ b/src/園児台帳/main.mobile.js @@ -0,0 +1,41 @@ + +(function () { + "use strict"; + const FIELD_CODE = "ユニークキー"; + + // ------------------- 詳細/印刷/編集画面表示時の処理 ------------------- + kintone.events.on(['mobile.app.record.detail.show'], function (event) { + hideField(FIELD_CODE); + return event; + }); + + // ------------------- 編集画面表示時の処理 ------------------- + kintone.events.on(['mobile.app.record.edit.show', 'mobile.app.record.create.show'], function (event) { + const targetFieldEl = kintone.mobile.app.record.getSpaceElement("before-unique-key").nextSibling; + targetFieldEl.querySelector('.control-constraints-gaia').style.display = 'none'; + + event.record[FIELD_CODE]['value'] = "<自動計算:出席番号+学年+クラス+名前>"; + disableField(event.record, FIELD_CODE); + return event; + }); + + + function hideField(fieldCode) { + kintone.mobile.app.record.setFieldShown(fieldCode, false); + } + + function disableField(record, fieldCode) { + record[fieldCode]['disabled'] = true; + } + + // ------------------- 編集画面保存時の処理 ------------------- + kintone.events.on(['mobile.app.record.create.submit', 'mobile.app.record.edit.submit'], function (event) { + event.record[FIELD_CODE]['value'] = getUniqueKey(event.record); + return event; + }); + + function getUniqueKey(record) { + return (record['出席番号']['value'] + '_' + record['学年']['value'] + '_' + record['クラス']['value'] + '_' + record['名前']['value']).substring(0, 64); + } + +})(); \ No newline at end of file