feat: TBM 모바일 시스템 + 작업 분할/이동 + 권한 통합
TBM 시스템: - 4단계 워크플로우 (draft→세부편집→완료→작업보고) - 모바일 전용 TBM 페이지 (tbm-mobile.html) + 3단계 생성 위자드 - 작업자 작업 분할 (work_hours + split_seq) - 작업자 이동 보내기/빼오기 (tbm_transfers 테이블) - 생성 시 중복 배정 방지 (당일 배정 현황 조회) - 데스크탑 TBM 페이지 세부편집 기능 추가 작업보고서: - 모바일 전용 작업보고서 페이지 (report-create-mobile.html) - TBM에서 사전 등록된 work_hours 자동 반영 권한 시스템: - tkuser user_page_permissions 테이블과 system1 페이지 접근 연동 - pageAccessRoutes를 userRoutes보다 먼저 등록 (라우트 우선순위 수정) - TKUSER_DEFAULT_ACCESS 폴백 추가 (개인→부서→기본값 3단계) - 권한 캐시키 갱신 (userPageAccess_v2) 기타: - app-init.js 캐시 버스팅 (v=5) - iOS Safari touch-action: manipulation 적용 - KST 타임존 날짜 버그 수정 (toISOString UTC 이슈) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -218,16 +218,36 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 지도 영역 */
|
||||
/* 작업장 카드: 엣지투엣지 */
|
||||
.workplace-status-section .card {
|
||||
border-radius: 0;
|
||||
margin-left: -0.75rem;
|
||||
margin-right: -0.75rem;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.workplace-status-section .card-body {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
#workplaceMapContainer {
|
||||
min-height: 300px !important;
|
||||
min-height: auto !important;
|
||||
}
|
||||
|
||||
/* 캔버스: 높이 제한 해제, 풀와이드 */
|
||||
#workplaceMapCanvas {
|
||||
max-height: 350px;
|
||||
max-height: none;
|
||||
border-radius: 0 !important;
|
||||
border-left: none !important;
|
||||
border-right: none !important;
|
||||
}
|
||||
|
||||
/* 범례 숨기기 또는 축소 */
|
||||
.workplace-status-section .card-header {
|
||||
padding: 0.75rem !important;
|
||||
}
|
||||
|
||||
/* 범례 숨기기 */
|
||||
#mapLegend {
|
||||
display: none;
|
||||
}
|
||||
@@ -756,6 +776,264 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== 모바일 대시보드 (작업장 리스트 뷰) ========== */
|
||||
@media (max-width: 768px) {
|
||||
/* 모바일 뷰가 활성화되면 데스크톱 섹션 숨김 */
|
||||
.mobile-dashboard-view[style*="block"] ~ .workplace-status-section,
|
||||
.mobile-dashboard-view[style*="block"] ~ .moved-equipment-section,
|
||||
.mobile-dashboard-view[style*="block"] ~ .dashboard-footer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mobile-dashboard-view {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
/* --- 날짜 헤더 --- */
|
||||
.md-date-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
margin-bottom: 14px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.md-date-label {
|
||||
font-size: var(--text-lg, 18px);
|
||||
font-weight: 700;
|
||||
color: var(--text-primary, #1a202c);
|
||||
}
|
||||
|
||||
.md-date-value {
|
||||
font-size: var(--text-sm, 14px);
|
||||
color: var(--text-tertiary, #718096);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* --- 카테고리 탭 --- */
|
||||
.md-category-tabs {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
padding: 0 2px 12px;
|
||||
margin-bottom: 4px;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.md-category-tabs::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.md-cat-tab {
|
||||
flex-shrink: 0;
|
||||
padding: 7px 16px;
|
||||
border-radius: var(--radius-full, 9999px);
|
||||
font-size: var(--text-sm, 14px);
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
border: 1px solid var(--border-light, #e2e8f0);
|
||||
background: var(--bg-primary, #fff);
|
||||
color: var(--text-secondary, #4a5568);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
min-height: 36px;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.md-cat-tab:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
.md-cat-tab.active {
|
||||
background: var(--primary-500, #3b82f6);
|
||||
color: #fff;
|
||||
border-color: var(--primary-500, #3b82f6);
|
||||
}
|
||||
|
||||
/* --- 작업장 리스트 --- */
|
||||
.md-workplace-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* --- 작업장 카드 --- */
|
||||
.md-wp-card {
|
||||
background: var(--bg-primary, #fff);
|
||||
border: 1px solid var(--border-light, #e2e8f0);
|
||||
border-radius: var(--radius-lg, 12px);
|
||||
padding: 14px 16px;
|
||||
}
|
||||
|
||||
.md-wp-name {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary, #1a202c);
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
.md-wp-stats {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.md-wp-stat-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: var(--text-sm, 14px);
|
||||
color: var(--text-secondary, #4a5568);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.md-wp-stat-icon {
|
||||
flex-shrink: 0;
|
||||
width: 18px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.md-wp-stat-text {
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.md-wp-stat--warning {
|
||||
color: var(--status-warning-text, #ca8a04);
|
||||
}
|
||||
|
||||
/* --- 빈 상태 --- */
|
||||
.md-wp-no-activity {
|
||||
margin: 0;
|
||||
color: var(--text-tertiary, #718096);
|
||||
font-size: var(--text-sm, 14px);
|
||||
}
|
||||
|
||||
.md-wp-empty-all {
|
||||
text-align: center;
|
||||
padding: 32px 0;
|
||||
color: var(--text-tertiary, #718096);
|
||||
font-size: var(--text-sm, 14px);
|
||||
}
|
||||
|
||||
/* --- 카드 확장 상태 --- */
|
||||
.md-wp-card.expanded {
|
||||
border-color: var(--primary-300, #93c5fd);
|
||||
box-shadow: 0 2px 8px rgba(59,130,246,0.1);
|
||||
}
|
||||
|
||||
.md-wp-header {
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.md-wp-toggle {
|
||||
float: right;
|
||||
color: var(--text-tertiary, #718096);
|
||||
font-size: 12px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.md-wp-card.expanded .md-wp-toggle {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* --- 상세 영역 --- */
|
||||
.md-wp-detail {
|
||||
display: none;
|
||||
border-top: 1px solid var(--border-light, #e2e8f0);
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.md-wp-card.expanded .md-wp-detail {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.md-wp-detail-section {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.md-wp-detail-section:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.md-wp-detail-title {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--text-tertiary, #718096);
|
||||
letter-spacing: 0.03em;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.md-wp-detail-item {
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px solid var(--gray-100, #f5f5f5);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.md-wp-detail-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.md-wp-detail-main {
|
||||
font-weight: 500;
|
||||
color: var(--text-primary, #1a202c);
|
||||
}
|
||||
|
||||
.md-wp-detail-sub {
|
||||
font-size: 13px;
|
||||
color: var(--text-tertiary, #718096);
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
/* 신고 상태 배지 */
|
||||
.md-wp-issue-status {
|
||||
display: inline-block;
|
||||
font-size: 11px;
|
||||
padding: 1px 6px;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.md-wp-issue-status--reported {
|
||||
background: var(--status-warning-bg, #fef3c7);
|
||||
color: var(--status-warning-text, #ca8a04);
|
||||
}
|
||||
|
||||
.md-wp-issue-status--received {
|
||||
background: var(--status-info-bg, #dbeafe);
|
||||
color: var(--status-info-text, #2563eb);
|
||||
}
|
||||
|
||||
.md-wp-issue-status--in_progress {
|
||||
background: var(--status-error-bg, #fee2e2);
|
||||
color: var(--status-error-text, #dc2626);
|
||||
}
|
||||
|
||||
/* --- 로딩 스켈레톤 --- */
|
||||
.md-skeleton {
|
||||
height: 48px;
|
||||
border-radius: var(--radius-md, 8px);
|
||||
background: linear-gradient(90deg, var(--gray-100, #f5f5f5) 25%, var(--gray-200, #eee) 50%, var(--gray-100, #f5f5f5) 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: md-shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes md-shimmer {
|
||||
0% { background-position: 200% 0; }
|
||||
100% { background-position: -200% 0; }
|
||||
}
|
||||
}
|
||||
|
||||
/* 데스크톱에서는 모바일 대시보드 절대 표시 안 함 */
|
||||
@media (min-width: 769px) {
|
||||
.mobile-dashboard-view {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== 다크모드 지원 (선택적) ========== */
|
||||
@media (max-width: 768px) and (prefers-color-scheme: dark) {
|
||||
/* 다크모드 색상 조정 필요시 여기에 추가 */
|
||||
|
||||
Reference in New Issue
Block a user