Created
February 28, 2019 19:45
-
-
Save iErik/7c2ca9d66cd02be44e166097a8880938 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <template> | |
| <c-card class="employee-info-card" no-border no-hover> | |
| <div class="heading"> | |
| <slot> | |
| <c-title class="title" :grey="isMobile && hideContents"> | |
| {{ title }} | |
| </c-title> | |
| <div class="actions"> | |
| <c-button | |
| v-if="vacation" | |
| class="btn" | |
| :size="isMobile ? '30' : '40'" | |
| @click="$emit('edit')" | |
| > | |
| Solicitar férias | |
| </c-button> | |
| <c-button | |
| v-else | |
| flat | |
| class="btn edit" | |
| icon="pencil" | |
| :size="isMobile ? '30' : '40'" | |
| :icon-size="isMobile ? '15' : '20'" | |
| :disabled="loading" | |
| @click="$emit('edit')" | |
| /> | |
| <c-button | |
| v-if="isMobile" | |
| flat | |
| size="30" | |
| icon-size="15" | |
| icon="chevron-up" | |
| :class="['btn toggle', { '-reverse': hideContents }]" | |
| @click="hideContents = !hideContents" | |
| /> | |
| </div> | |
| </slot> | |
| </div> | |
| <div | |
| ref="wrapper" | |
| :style="{ height: isMobile && hideContents ? '0px' : `${contentHeight}px` }" | |
| :class="['wrapper', { '-hidden': hideContents }]" | |
| > | |
| <info-chunk ref="content" :fields="infoFields" /> | |
| </div> | |
| </c-card> | |
| </template> | |
| <script> | |
| import { is } from 'convenia-components' | |
| import MediaQuery from '@mixins/MediaQuery' | |
| import InfoChunk from '@common/InfoChunk' | |
| export default { | |
| components: { InfoChunk }, | |
| mixins: [ MediaQuery ], | |
| props: { | |
| /** | |
| * The title of the card. | |
| */ | |
| title: { | |
| type: String, | |
| required: true | |
| }, | |
| fields: { | |
| type: Object, | |
| required: true | |
| }, | |
| /** | |
| * Whether it's contents are loading or not. | |
| */ | |
| loading: Boolean, | |
| /** | |
| * Whether it is editable or not. | |
| */ | |
| editable: Boolean, | |
| vacation: Boolean | |
| }, | |
| data () { | |
| return { | |
| hideContents: false, | |
| contentObs: null, | |
| contentHeight: 0 | |
| } | |
| }, | |
| computed: { | |
| infoFields () { | |
| return Object.keys(this.fields) | |
| .map(fieldName => { | |
| const field = this.fields[fieldName] | |
| const infoCardProps = field.infoCardProps || {} | |
| return { | |
| ...field, | |
| name: fieldName, | |
| hidden: is(infoCardProps.isHidden, 'Function') && infoCardProps.isHidden(this.fields), | |
| value: this.getFieldValue(field) | |
| } | |
| }) | |
| } | |
| }, | |
| methods: { | |
| getFieldValue (field) { | |
| if (is((field.infoCardProps || {}).value, 'Function')) | |
| return field.infoCardProps.value(this.fields, field.value) | |
| return field.value | |
| } | |
| }, | |
| mounted () { | |
| this.contentObs = new ResizeObserver(ev => { | |
| this.contentHeight = ev[0].target.scrollHeight | |
| }) | |
| this.contentObs.observe(this.$refs.content.$el) | |
| } | |
| } | |
| </script> | |
| <style lang="scss"> | |
| .employee-info-card { | |
| padding: 10px; | |
| margin: 0 10px 20px 10px; | |
| &:last-child { margin-bottom: 185px; } | |
| // Maybe move this to the CCard itself. | |
| @include responsive (tablet, desktop) { | |
| padding: 20px; | |
| margin: 0 5px 20px 0; | |
| } | |
| & > .heading { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| // Card Title | |
| & > .title > .text { color: map-get($text-color, base-80); } | |
| & > .actions { | |
| display: flex; | |
| // Buttons (actions) | |
| & > .btn { margin-left: 10px; } | |
| & > .btn.edit { margin-left: auto; } | |
| & > .btn.toggle { | |
| transform: rotate(0deg); | |
| transition: transform .2s; | |
| & > .icon { margin-bottom: 1px; } | |
| &.-reverse { transform: rotate(180deg); } | |
| &.-reverse > .icon { margin-bottom: 3px; } | |
| } | |
| } | |
| } | |
| & > .wrapper { transition: height .3s; } | |
| & > .wrapper > .content { | |
| display: flex; | |
| flex-direction: column; | |
| padding: 30px 0 30px 10px; | |
| @include responsive (tablet, desktop) { padding: 30px 0 20px; } | |
| & > .info { | |
| position: relative; | |
| display: flex; | |
| flex-direction: column; | |
| min-height: 20px; | |
| &:not(:last-child) { margin-bottom: 20px; } | |
| @include responsive (tablet, desktop) { | |
| flex-direction: row; | |
| margin-left: 250px; | |
| &:not(:last-child) { margin-bottom: 10px; } | |
| } | |
| } | |
| & > .info > .label { | |
| font-size: 11px; | |
| font-family: $title-font-family; | |
| font-weight: $title-font-weight; | |
| color: map-get($text-color, base-50); | |
| margin-bottom: 5px; | |
| text-transform: uppercase; | |
| -webkit-font-smoothing: antialiased; | |
| @include responsive (tablet, desktop) { | |
| position: absolute; | |
| top: 50%; | |
| margin: 0; | |
| transform: translate(calc(-100% - 30px), -50%); | |
| } | |
| } | |
| & > .info > .value { | |
| font-size: 14px; | |
| color: map-get($text-color, base-80); | |
| text-transform: capitalize; | |
| } | |
| } | |
| } | |
| </style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment