You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
3.4 KiB

  1. <script lang="ts">
  2. import type { IconName, iconNames } from "../external/icons";
  3. import { formatTime } from "../utils/time";
  4. import DaysLeft from "./DaysLeft.svelte";
  5. import Icon from "./Icon.svelte";
  6. import LinkHook from "./LinkHook.svelte";
  7. import Markdown from "./Markdown.svelte";
  8. interface ActualParent {
  9. id: string
  10. name: string
  11. }
  12. interface EntryCommon {
  13. id: string
  14. name?: string
  15. description: string
  16. icon?: IconName
  17. startTime?: string
  18. endTime?: string
  19. createdTime?: string
  20. loggedTime?: string
  21. active?: boolean
  22. completedAmount?: number
  23. itemAmount?: number
  24. task?: EntryCommonSub
  25. }
  26. interface EntryCommonSub {
  27. name: string
  28. icon: IconName
  29. }
  30. export let entry: EntryCommon = null;
  31. export let actualParent: ActualParent = null;
  32. export let hideParentName: boolean = false;
  33. let iconName: IconName;
  34. let displayName: string;
  35. let displayTime: string;
  36. $: iconName = entry.task?.icon || entry.icon;
  37. $: displayName = entry.name || entry.task?.name || "";
  38. $: displayTime = entry.loggedTime ? formatTime(entry.loggedTime) : "";
  39. </script>
  40. <div class="child-entry">
  41. <LinkHook id={entry.id} />
  42. <div class="body">
  43. <div class="header">
  44. <slot name="icon">
  45. <div class="icon">
  46. <Icon name={iconName} />
  47. </div>
  48. </slot>
  49. {#if (actualParent != null)}
  50. {#if !hideParentName}
  51. <div class="actual-parent-icon">
  52. <Icon block name="link" />
  53. </div>
  54. <div class="actual-parent">
  55. <a href={`/questlog#${actualParent.id}`}>{actualParent.name}</a>
  56. </div>
  57. {/if}
  58. {/if}
  59. <div class="name">{displayName}</div>
  60. {#if (entry.endTime != null)}
  61. <div class="times">
  62. <DaysLeft startTime={entry.startTime || entry.createdTime} endTime={entry.endTime} />
  63. </div>
  64. {/if}
  65. {#if (displayTime != null)}
  66. <div class="times">
  67. {displayTime}
  68. </div>
  69. {/if}
  70. </div>
  71. <div class="entry-body">
  72. <Markdown source={entry.description} />
  73. <slot></slot>
  74. </div>
  75. </div>
  76. </div>
  77. <style>
  78. div.child-entry {
  79. display: flex;
  80. flex-direction: row;
  81. margin: 0.25em 0 0.75em 0;
  82. }
  83. div.icon, div.child-entry div.header :global(div.icon-like) {
  84. display: flex;
  85. flex-direction: column;
  86. font-size: 1em;
  87. padding: 0.2em .5ch;
  88. margin-right: 0.5em;
  89. background: #444;
  90. color: #CCC;
  91. }
  92. div.body {
  93. display: flex;
  94. flex-direction: column;
  95. width: 100%;
  96. }
  97. div.header {
  98. display: flex;
  99. flex-direction: row;
  100. background: #333;
  101. }
  102. div.actual-parent-icon {
  103. display: flex;
  104. flex-direction: column;
  105. font-size: 1em;
  106. padding: 0.3em 0;
  107. padding-bottom: 0.1em;
  108. margin-right: 0.5em;
  109. color: #555;
  110. }
  111. div.actual-parent {
  112. font-size: 1em;
  113. font-weight: 100;
  114. margin: auto 0;
  115. vertical-align: middle;
  116. padding: 0.125em 0;
  117. padding-right: 1ch;
  118. display: flex;
  119. flex-direction: row;
  120. }
  121. div.actual-parent :global(div.icon) {
  122. display: none !important;
  123. }
  124. div.name {
  125. font-size: 1em;
  126. font-weight: 100;
  127. margin: auto 0;
  128. vertical-align: middle;
  129. padding: 0.125em .5ch;
  130. }
  131. div.times {
  132. margin-left: auto;
  133. margin-right: 0.25ch;
  134. padding: 0.125em 0;
  135. }
  136. div.entry-body {
  137. padding: 0.25em 1ch;
  138. background: #222;
  139. color: #aaa;
  140. border-bottom-right-radius: 0.5em;
  141. }
  142. </style>