diff --git a/app/javascript/components/ElapsedDays.jsx b/app/javascript/components/ElapsedDays.jsx index a33d801da7e..0e1f05516a6 100644 --- a/app/javascript/components/ElapsedDays.jsx +++ b/app/javascript/components/ElapsedDays.jsx @@ -10,7 +10,7 @@ export default function ElapsedDays({ countProductsGroupedBy }) {
  1. @@ -20,7 +20,7 @@ export default function ElapsedDays({ countProductsGroupedBy }) {
  2. @@ -30,7 +30,7 @@ export default function ElapsedDays({ countProductsGroupedBy }) {
  3. diff --git a/app/javascript/components/Products.jsx b/app/javascript/components/Products.jsx index 6884559109c..7afff830b5a 100644 --- a/app/javascript/components/Products.jsx +++ b/app/javascript/components/Products.jsx @@ -209,13 +209,13 @@ function ProductHeader({ elapsedDaysId, countProductsGroupedBy }) { - let headerClass = 'card-header a-elapsed-days' + let headerClass = 'card-header a-highlight' if (productsNDaysPassed.elapsed_days === 5) { - headerClass += ' is-reply-warning' + headerClass += ' is-warning' } else if (productsNDaysPassed.elapsed_days === 6) { - headerClass += ' is-reply-alert' + headerClass += ' is-alert' } else if (productsNDaysPassed.elapsed_days >= 7) { - headerClass += ' is-reply-deadline' + headerClass += ' is-danger' } const headerLabel = () => { diff --git a/app/javascript/product.vue b/app/javascript/product.vue index 2c208d3e779..dcf1765b634 100644 --- a/app/javascript/product.vue +++ b/app/javascript/product.vue @@ -45,13 +45,22 @@ span.a-meta__label 更新 | {{ product.updated_at }} .card-list-item-meta__item( - v-if='isUnassignedProductsPage || isDashboardPage') + v-if='isGroupedByDaysElapsed && (isUnassignedProductsPage || isDashboardPage)') time.a-meta(v-if='untilNextElapsedDays(product) < 1') span.a-meta__label 次の経過日数まで | 1時間未満 time.a-meta(v-else-if='calcElapsedTimes(product) < 7') span.a-meta__label 次の経過日数まで | 約{{ untilNextElapsedDays(product) }}時間 + .card-list-item-meta__item(v-else) + time.a-meta + span.a-meta__label 研修終了日 + span.a-meta__value {{ product.user.training_ends_on }} + span.a-meta__value.is-danger( + v-if='product.user.training_remaining_days === 0') + | (本日研修最終日) + span.a-meta__value.is-danger(v-else) + | (あと{{ product.user.training_remaining_days }}日) hr.card-list-item__row-separator(v-if='product.comments.size > 0') .card-list-item__row(v-if='product.comments.size > 0') @@ -123,7 +132,8 @@ export default { product: { type: Object, required: true }, isMentor: { type: Boolean, required: true }, currentUserId: { type: Number, required: true }, - displayUserIcon: { type: Boolean } + displayUserIcon: { type: Boolean }, + isGroupedByDaysElapsed: { type: Boolean } }, computed: { roleClass() { diff --git a/app/javascript/products.vue b/app/javascript/products.vue index 2353e962714..873aec8da14 100644 --- a/app/javascript/products.vue +++ b/app/javascript/products.vue @@ -17,12 +17,30 @@ //- ダッシュボード .is-vue(v-else-if='isDashboard') + template(v-if='traineeProductsEndDateWithin7Days.length > 0') + .a-card.h-auto + header.card-header.a-highlight.is-danger + h2.card-header__title + | 研修終了まで7日以内 + span.card-header__count ({{ traineeProductsEndDateWithin7Days.length }}) + + .card-list + .card-list__items + product( + v-for='product in traineeProductsEndDateWithin7Days', + :key='product.id', + :product='product', + :currentUserId='currentUserId', + :isMentor='isMentor', + :display-user-icon='displayUserIcon', + :isGroupedByDaysElapsed='false') + template(v-for='product_n_days_passed in productsGroupedByElapsedDays') .a-card.h-auto( v-if='!isDashboard || (isDashboard && product_n_days_passed.elapsed_days >= 5)') //- TODO 以下を共通化する //- prettier-ignore: need space between v-if and id - header.card-header.a-elapsed-days( + header.card-header.a-highlight( v-if='product_n_days_passed.elapsed_days === 0', id='0days-elapsed' ) h2.card-header__title @@ -30,7 +48,7 @@ span.card-header__count | ({{ countProductsGroupedBy(product_n_days_passed) }}) //- prettier-ignore: need space between v-else-if and id - header.card-header.a-elapsed-days.is-reply-warning( + header.card-header.a-highlight.is-warning( v-else-if='product_n_days_passed.elapsed_days === 5', id='5days-elapsed' ) h2.card-header__title @@ -38,7 +56,7 @@ span.card-header__count | ({{ countProductsGroupedBy(product_n_days_passed) }}) //- prettier-ignore: need space between v-else-if and id - header.card-header.a-elapsed-days.is-reply-alert( + header.card-header.a-highlight.is-alert( v-else-if='product_n_days_passed.elapsed_days === 6', id='6days-elapsed' ) h2.card-header__title @@ -46,14 +64,14 @@ span.card-header__count | ({{ countProductsGroupedBy(product_n_days_passed) }}) //- prettier-ignore: need space between v-else-if and id - header.card-header.a-elapsed-days.is-reply-deadline( + header.card-header.a-highlight.is-danger( v-else-if='product_n_days_passed.elapsed_days === 7', id='7days-elapsed' ) h2.card-header__title | {{ product_n_days_passed.elapsed_days }}日以上経過 span.card-header__count | ({{ countProductsGroupedBy(product_n_days_passed) }}) - header.card-header.a-elapsed-days( + header.card-header.a-highlight( v-else, :id='elapsedDaysId(product_n_days_passed.elapsed_days)') h2.card-header__title @@ -70,7 +88,8 @@ :product='product', :currentUserId='currentUserId', :isMentor='isMentor', - :display-user-icon='displayUserIcon') + :display-user-icon='displayUserIcon', + :isGroupedByDaysElapsed='true') .under-cards .under-cards__links.mt-4.text-center.leading-normal.text-sm @@ -106,7 +125,8 @@ export default { return { products: [], loaded: false, - productsGroupedByElapsedDays: null + productsGroupedByElapsedDays: null, + traineeProductsEndDateWithin7Days: [] } }, computed: { @@ -153,6 +173,12 @@ export default { this.products = [] json.products.forEach((product) => { this.products.push(product) + if ( + product.user.training_remaining_days >= 0 && + product.user.training_remaining_days <= 7 + ) { + this.traineeProductsEndDateWithin7Days.push(product) + } }) this.loaded = true }) diff --git a/app/javascript/stylesheets/_common-imports.sass b/app/javascript/stylesheets/_common-imports.sass index 29ec59ded46..0199695c68d 100644 --- a/app/javascript/stylesheets/_common-imports.sass +++ b/app/javascript/stylesheets/_common-imports.sass @@ -87,7 +87,7 @@ @import "atoms/a-completion-message" @import "atoms/a-count-badge" @import "atoms/a-dropdown" -@import "atoms/a-elapsed-days" +@import "atoms/a-highlight" @import "atoms/a-empty-message" @import "atoms/a-file-input" @import "atoms/a-form-frame" diff --git a/app/javascript/stylesheets/atoms/_a-elapsed-days.sass b/app/javascript/stylesheets/atoms/_a-highlight.sass similarity index 82% rename from app/javascript/stylesheets/atoms/_a-elapsed-days.sass rename to app/javascript/stylesheets/atoms/_a-highlight.sass index d5b9d73af3e..775fd5d86b6 100644 --- a/app/javascript/stylesheets/atoms/_a-elapsed-days.sass +++ b/app/javascript/stylesheets/atoms/_a-highlight.sass @@ -1,6 +1,4 @@ -.card-header.a-elapsed-days - letter-spacing: .125em - text-indent: .125em +.card-header.a-highlight margin: -1px -1px 0 background-color: var(--base) border: solid 1px var(--border) @@ -12,14 +10,14 @@ +media-breakpoint-down(sm) +text-block(.875rem 1.4, 600 center) padding: .375rem .75rem - &.is-reply-warning + &.is-warning background-color: var(--reply-warning-background) border-color: var(--reply-warning-border) - &.is-reply-alert + &.is-alert color: var(--reversal-text) background-color: var(--reply-alert-background) border-color: var(--reply-alert-border) - &.is-reply-deadline + &.is-danger color: var(--reversal-text) background-color: var(--reply-deadline-background) border-color: var(--reply-deadline-border) diff --git a/app/javascript/stylesheets/shared/blocks/_page-nav.sass b/app/javascript/stylesheets/shared/blocks/_page-nav.sass index ae66ff8f897..c505be05600 100644 --- a/app/javascript/stylesheets/shared/blocks/_page-nav.sass +++ b/app/javascript/stylesheets/shared/blocks/_page-nav.sass @@ -64,11 +64,11 @@ a.page-nav__title-inner font-weight: 700 &.is-current +page-nav-current(var(--primary-tint), var(--primary), var(--primary-text), true) - &.is-reply-warning + &.is-warning +page-nav-current(var(--reply-warning-background), var(--reply-warning-border), var(--default-text), false) - &.is-reply-alert + &.is-alert +page-nav-current(var(--reply-alert-background), var(--reply-alert-border), var(--reversal-text), false) - &.is-reply-deadline + &.is-danger +page-nav-current(var(--reply-deadline-background), var(--reply-deadline-border), var(--reversal-text), false) &.is-inactive position: static diff --git a/test/system/home_test.rb b/test/system/home_test.rb index d25fad227ae..dd31790afb1 100644 --- a/test/system/home_test.rb +++ b/test/system/home_test.rb @@ -322,6 +322,78 @@ def assert_events_count(event_label, count) assert_no_text '今日提出(48)' end + test 'show products of trainees whose training end date is within 7 days' do + user_kensyu_end_within_1_week = User.create!( + login_name: 'kensyu-end-within-1-week', + email: 'kensyu-end-within-1-week@fjord.jp', + password: 'testtest', + name: 'kensyu-end-within-1-week', + name_kana: 'ケンシュウ モウスコシデシュウリョウ', + company: companies(:company2), + description: 'test', + course: courses(:course1), + job: 'office_worker', + os: 'mac', + experience: 'inexperienced', + trainee: true, + training_ends_on: Time.current + 7.days + ) + user_kensyu_end_within_24_hour = User.create!( + login_name: 'kensyu-end-within-24-hour', + email: 'kensyu-end-within-24-hour@fjord.jp', + password: 'testtest', + name: 'kensyu-end-within-24-hour', + name_kana: 'ケンシュウ キョウシュウリョウ', + company: companies(:company2), + description: 'test', + course: courses(:course1), + job: 'office_worker', + os: 'mac', + experience: 'inexperienced', + trainee: true, + training_ends_on: Time.current + ) + practice1 = practices(:practice1) + practice2 = practices(:practice2) + product1 = Product.create!( + practice_id: practice1.id, + user_id: user_kensyu_end_within_1_week.id, + body: '研修終了日が1週間以内の研修生の提出物' + ) + product2 = Product.create!( + practice_id: practice2.id, + user_id: user_kensyu_end_within_24_hour.id, + body: '今日研修が終了する研修生の提出物' + ) + + visit_with_auth '/', 'mentormentaro' + assert_text '研修終了まで7日以内(2)' + within all('.card-list-item')[0] do + assert_text 'OS X Mountain Lionをクリーンインストールするの提出物' + assert_text 'kensyu-end-within-1-week (ケンシュウ モウスコシデシュウリョウ)' + assert_selector '.a-meta__label', text: '提出' + assert_text I18n.l product1.created_at, format: :default + assert_selector '.a-meta__label', text: '更新' + assert_text I18n.l product1.updated_at, format: :default + assert_selector '.a-meta__label', text: '研修終了日' + assert_text I18n.l user_kensyu_end_within_1_week.training_ends_on, format: :default + assert_selector '.a-meta__value.is-danger', text: '(あと7日)' + assert_selector 'button', text: '担当する' + end + within all('.card-list-item')[1] do + assert_text 'Terminalの基礎を覚えるの提出物' + assert_text 'kensyu-end-within-24-hour (ケンシュウ キョウシュウリョウ)' + assert_selector '.a-meta__label', text: '提出' + assert_text I18n.l product2.created_at, format: :default + assert_selector '.a-meta__label', text: '更新' + assert_text I18n.l product2.updated_at, format: :default + assert_selector '.a-meta__label', text: '研修終了日' + assert_text I18n.l user_kensyu_end_within_24_hour.training_ends_on, format: :default + assert_selector '.a-meta__value.is-danger', text: '(本日研修最終日)' + assert_selector 'button', text: '担当する' + end + end + test 'display counts of passed almost 5days' do visit_with_auth '/', 'mentormentaro' assert_text "2件の提出物が、\n8時間以内に5日経過に到達します。"