OaTaskCard.vue 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. <template>
  2. <view class="oa-task-card" :class="'tone-' + normalizedTone">
  3. <view class="oa-task-card__body" @click="$emit('open')">
  4. <view class="oa-task-card__top">
  5. <view class="oa-task-card__title-row">
  6. <view v-if="unread" class="oa-task-card__unread" aria-hidden="true" />
  7. <text class="oa-task-card__title">{{ title }}</text>
  8. </view>
  9. <text
  10. v-if="statusText"
  11. class="oa-task-card__status"
  12. :class="'is-' + normalizedTone"
  13. >
  14. {{ statusText }}
  15. </text>
  16. </view>
  17. <view v-if="metaLines && metaLines.length" class="oa-task-card__meta">
  18. <view
  19. v-for="(line, idx) in metaLines"
  20. :key="idx"
  21. class="oa-task-card__meta-line"
  22. >
  23. <text class="oa-task-card__meta-label">{{ line.label }}</text>
  24. <text class="oa-task-card__meta-value">{{ line.value }}</text>
  25. </view>
  26. </view>
  27. </view>
  28. <view v-if="actions && actions.length" class="oa-task-card__footer">
  29. <view
  30. v-for="act in actions"
  31. :key="act.key"
  32. class="oa-task-card__btn"
  33. :class="{
  34. 'is-primary': !!act.primary,
  35. 'is-danger': !!act.danger && !act.primary
  36. }"
  37. @click.stop="$emit('action', act)"
  38. >
  39. {{ act.label }}
  40. </view>
  41. </view>
  42. </view>
  43. </template>
  44. <script>
  45. const TONES = ['warn', 'success', 'danger', 'info']
  46. export default {
  47. name: 'OaTaskCard',
  48. props: {
  49. title: { type: String, default: '' },
  50. statusText: { type: String, default: '' },
  51. statusTone: { type: String, default: 'info' },
  52. metaLines: { type: Array, default: () => [] },
  53. unread: { type: Boolean, default: false },
  54. actions: { type: Array, default: () => [] }
  55. },
  56. emits: ['open', 'action'],
  57. computed: {
  58. normalizedTone() {
  59. const t = String(this.statusTone || 'info').toLowerCase()
  60. return TONES.includes(t) ? t : 'info'
  61. }
  62. }
  63. }
  64. </script>