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.

122 lines
2.6 KiB

  1. <script lang="ts">
  2. import type { IconName } from "../external/icons";
  3. import type { TaskResult } from "../models/task";
  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. import ProjectProgress from "./ProjectProgress.svelte";
  9. interface EntryIconHolder {
  10. icon: IconName
  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. group?: EntryIconHolder
  21. project?: EntryIconHolder
  22. tasks?: TaskResult[]
  23. active?: boolean
  24. }
  25. export let entry: EntryCommon;
  26. export let full = false;
  27. export let headerLink = "";
  28. export let hideProgress: boolean = false;
  29. export let hideIcon: boolean = false;
  30. let iconName: IconName;
  31. $: {
  32. if (entry.project != null) {
  33. iconName = entry.project.icon;
  34. } else if (entry.group != null) {
  35. iconName = entry.group.icon;
  36. } else {
  37. iconName = entry.icon || "question";
  38. }
  39. }
  40. </script>
  41. <div class="parent-entry" class:full={full}>
  42. <LinkHook id={entry.id} />
  43. {#if !hideIcon}
  44. <div class="icon" class:completed={entry.active === false}>
  45. <Icon block name={iconName} />
  46. </div>
  47. {/if}
  48. <div class="body">
  49. <div class="header">
  50. <div class="name">
  51. {#if headerLink}
  52. <a href={headerLink}>{entry.name}</a>
  53. {:else}
  54. {entry.name}
  55. {/if}
  56. </div>
  57. {#if entry.endTime != null}
  58. <div class="days-left">
  59. <DaysLeft startTime={entry.startTime || entry.createdTime} endTime={entry.endTime} />
  60. </div>
  61. {/if}
  62. </div>
  63. {#if (!hideProgress && entry.tasks != null)}
  64. <ProjectProgress project={entry} />
  65. {/if}
  66. {#if (full)}
  67. <Markdown source={entry.description} />
  68. {/if}
  69. <slot></slot>
  70. </div>
  71. </div>
  72. <style>
  73. div.parent-entry {
  74. display: flex;
  75. flex-direction: row;
  76. padding-bottom: 0.5em;
  77. }
  78. div.parent-entry.full {
  79. padding-bottom: 1em;
  80. }
  81. div.icon {
  82. font-size: 2em;
  83. padding: 0 0.5ch;
  84. width: 2ch;
  85. padding-top: 0.125em;
  86. color: #333;
  87. }
  88. div.icon.completed {
  89. color: #484;
  90. }
  91. div.body {
  92. display: flex;
  93. flex-direction: column;
  94. width: 100%;
  95. }
  96. div.header {
  97. display: flex;
  98. flex-direction: row;
  99. }
  100. div.name {
  101. font-size: 1em;
  102. margin: auto 0;
  103. vertical-align: middle;
  104. font-weight: 100;
  105. }
  106. div.days-left {
  107. margin-left: auto;
  108. margin-right: 0.25ch;
  109. }
  110. a {
  111. color: inherit;
  112. text-decoration-color: #777;
  113. }
  114. </style>