Loading client/src/components/Common/GCard.vue +47 −40 Original line number Diff line number Diff line Loading @@ -266,7 +266,7 @@ async function toggleBookmark() { bookmarkLoading.value = false; } const { renderMarkdown } = useMarkdown({ openLinksInNewPage: true }); const { renderMarkdown } = useMarkdown({ noMargin: true, openLinksInNewPage: true }); /** * Helper functions for generating consistent element IDs Loading Loading @@ -335,12 +335,13 @@ function onKeyDown(event: KeyboardEvent) { :id="getElementId(props.id, 'title')" bold inline class="align-items-baseline" class="d-block" :size="props.titleSize"> <FontAwesomeIcon v-if="props.titleIcon?.icon" :icon="props.titleIcon.icon" class="mr-1" :class="props.titleIcon.class" :icon="props.titleIcon.icon" :title="props.titleIcon.title" :size="props.titleIcon.size" fixed-width /> Loading Loading @@ -516,7 +517,7 @@ function onKeyDown(event: KeyboardEvent) { <BButton v-if="(indicator.visible ?? true) && !indicator.disabled" :id="getIndicatorId(props.id, indicator.id)" :key="indicator.id" :key="`${indicator.id}-button`" v-b-tooltip.hover.noninteractive class="inline-icon-button" :title="localize(indicator.title)" Loading @@ -536,7 +537,7 @@ function onKeyDown(event: KeyboardEvent) { <FontAwesomeIcon v-else-if="(indicator.visible ?? true) && indicator.disabled" :id="getIndicatorId(props.id, indicator.id)" :key="indicator.id" :key="`${indicator.id}-icon`" v-b-tooltip.hover.noninteractive :title="localize(indicator.title)" :icon="indicator.icon" Loading @@ -549,16 +550,15 @@ function onKeyDown(event: KeyboardEvent) { </div> </div> <div :id="getElementId(props.id, 'description')"> <div :id="getElementId(props.id, 'description')" class="g-card-description"> <slot name="description"> <template v-if="props.description"> <TextSummary v-if="props.description && !props.fullDescription" v-if="!props.fullDescription" :id="getElementId(props.id, 'text-summary')" :description="props.description" /> <div v-else-if="props.description && props.fullDescription" class="mb-2" v-html="renderMarkdown(props.description)" /> <div v-else v-html="renderMarkdown(props.description)" /> </template> </slot> </div> </div> Loading Loading @@ -598,9 +598,13 @@ function onKeyDown(event: KeyboardEvent) { </div> </slot> <div class="align-items-center d-flex flex-gapx-1 justify-content-end ml-auto mt-1"> <div class="align-items-center d-flex flex-gapx-1 justify-content-end ml-auto"> <slot name="secondary-actions"> <BButtonGroup :id="getElementId(props.id, 'secondary-actions')" size="sm"> <BButtonGroup v-if="props.secondaryActions?.length" :id="getElementId(props.id, 'secondary-actions')" size="sm" class="mt-1"> <template v-for="sa in props.secondaryActions"> <BButton v-if="sa.visible ?? true" Loading Loading @@ -630,12 +634,14 @@ function onKeyDown(event: KeyboardEvent) { <div :id="getElementId(props.id, 'primary-actions')" class="d-flex flex-gapx-1"> <slot name="primary-actions"> <template v-if="props.primaryActions?.length"> <template v-for="pa in props.primaryActions"> <BButton v-if="pa.visible ?? true" :id="getActionId(props.id, pa.id)" :key="pa.id" v-b-tooltip.hover.noninteractive class="mt-1" :disabled="pa.disabled" :title="localize(pa.title)" :variant="pa.variant || 'primary'" Loading @@ -655,6 +661,7 @@ function onKeyDown(event: KeyboardEvent) { {{ localize(pa.label) }} </BButton> </template> </template> </slot> </div> </div> Loading client/src/components/Common/TextSummary.vue +1 −1 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ interface Props { oneLineSummary?: boolean; /** If `true`, doesn't show expand/collapse buttons */ noExpand?: boolean; /** The component to use for the summary, default = `<p>` */ /** The component to use for the summary, default = `<span>` */ component?: string; /** If `true`, shows the full text */ showExpandText?: boolean; Loading client/src/components/ScrollList/ScrollList.vue +1 −1 Original line number Diff line number Diff line Loading @@ -223,13 +223,13 @@ watch( </slot> <component :is="props.gridView ? 'div' : BListGroup" class="pt-1" :class="{ 'card-list d-flex flex-wrap': props.gridView }"> <!-- Use component wrapper with v-for to provide proper keying while avoiding layout interference --> <component :is="'div'" v-for="(item, index) in items" :key="itemKey(item)" class="" style="display: contents"> <slot name="item" :item="item" :index="index" /> </component> Loading client/src/components/Workflow/List/WorkflowCardList.vue +1 −1 Original line number Diff line number Diff line Loading @@ -92,7 +92,7 @@ const workflowPublished = ref<InstanceType<typeof WorkflowPublished>>(); </script> <template> <div class="workflow-card-list d-flex flex-wrap overflow-auto"> <div class="workflow-card-list d-flex flex-wrap overflow-auto pt-1"> <WorkflowCard v-for="workflow in workflows" :ref="props.itemRefs[workflow.id]" Loading client/src/composables/markdown.ts +15 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,16 @@ function addRuleHeadingIncreaseLevel(engine: MarkdownIt, increaseBy: number) { }; } function addRuleNoMargin(engine: MarkdownIt) { engine.renderer.rules.paragraph_open = function (tokens, idx, options, env, self) { const token = tokens[idx]; if (token) { token.attrPush(["style", "margin:0"]); } return self.renderToken(tokens, idx, options); }; } /** * Add a rule that removes newlines after list items. */ Loading Loading @@ -138,6 +148,7 @@ interface UseMarkdownOptions { openLinksInNewPage?: boolean; increaseHeadingLevelBy?: number; removeNewlinesAfterList?: boolean; noMargin?: boolean; } type RawMarkdown = string; Loading @@ -155,6 +166,10 @@ export function useMarkdown(options: UseMarkdownOptions = {}) { addRuleHeadingIncreaseLevel(mdEngine, options.increaseHeadingLevelBy); } if (options.noMargin) { addRuleNoMargin(mdEngine); } if (options.removeNewlinesAfterList) { addRuleRemoveNewlinesAfterList(mdEngine); } Loading Loading
client/src/components/Common/GCard.vue +47 −40 Original line number Diff line number Diff line Loading @@ -266,7 +266,7 @@ async function toggleBookmark() { bookmarkLoading.value = false; } const { renderMarkdown } = useMarkdown({ openLinksInNewPage: true }); const { renderMarkdown } = useMarkdown({ noMargin: true, openLinksInNewPage: true }); /** * Helper functions for generating consistent element IDs Loading Loading @@ -335,12 +335,13 @@ function onKeyDown(event: KeyboardEvent) { :id="getElementId(props.id, 'title')" bold inline class="align-items-baseline" class="d-block" :size="props.titleSize"> <FontAwesomeIcon v-if="props.titleIcon?.icon" :icon="props.titleIcon.icon" class="mr-1" :class="props.titleIcon.class" :icon="props.titleIcon.icon" :title="props.titleIcon.title" :size="props.titleIcon.size" fixed-width /> Loading Loading @@ -516,7 +517,7 @@ function onKeyDown(event: KeyboardEvent) { <BButton v-if="(indicator.visible ?? true) && !indicator.disabled" :id="getIndicatorId(props.id, indicator.id)" :key="indicator.id" :key="`${indicator.id}-button`" v-b-tooltip.hover.noninteractive class="inline-icon-button" :title="localize(indicator.title)" Loading @@ -536,7 +537,7 @@ function onKeyDown(event: KeyboardEvent) { <FontAwesomeIcon v-else-if="(indicator.visible ?? true) && indicator.disabled" :id="getIndicatorId(props.id, indicator.id)" :key="indicator.id" :key="`${indicator.id}-icon`" v-b-tooltip.hover.noninteractive :title="localize(indicator.title)" :icon="indicator.icon" Loading @@ -549,16 +550,15 @@ function onKeyDown(event: KeyboardEvent) { </div> </div> <div :id="getElementId(props.id, 'description')"> <div :id="getElementId(props.id, 'description')" class="g-card-description"> <slot name="description"> <template v-if="props.description"> <TextSummary v-if="props.description && !props.fullDescription" v-if="!props.fullDescription" :id="getElementId(props.id, 'text-summary')" :description="props.description" /> <div v-else-if="props.description && props.fullDescription" class="mb-2" v-html="renderMarkdown(props.description)" /> <div v-else v-html="renderMarkdown(props.description)" /> </template> </slot> </div> </div> Loading Loading @@ -598,9 +598,13 @@ function onKeyDown(event: KeyboardEvent) { </div> </slot> <div class="align-items-center d-flex flex-gapx-1 justify-content-end ml-auto mt-1"> <div class="align-items-center d-flex flex-gapx-1 justify-content-end ml-auto"> <slot name="secondary-actions"> <BButtonGroup :id="getElementId(props.id, 'secondary-actions')" size="sm"> <BButtonGroup v-if="props.secondaryActions?.length" :id="getElementId(props.id, 'secondary-actions')" size="sm" class="mt-1"> <template v-for="sa in props.secondaryActions"> <BButton v-if="sa.visible ?? true" Loading Loading @@ -630,12 +634,14 @@ function onKeyDown(event: KeyboardEvent) { <div :id="getElementId(props.id, 'primary-actions')" class="d-flex flex-gapx-1"> <slot name="primary-actions"> <template v-if="props.primaryActions?.length"> <template v-for="pa in props.primaryActions"> <BButton v-if="pa.visible ?? true" :id="getActionId(props.id, pa.id)" :key="pa.id" v-b-tooltip.hover.noninteractive class="mt-1" :disabled="pa.disabled" :title="localize(pa.title)" :variant="pa.variant || 'primary'" Loading @@ -655,6 +661,7 @@ function onKeyDown(event: KeyboardEvent) { {{ localize(pa.label) }} </BButton> </template> </template> </slot> </div> </div> Loading
client/src/components/Common/TextSummary.vue +1 −1 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ interface Props { oneLineSummary?: boolean; /** If `true`, doesn't show expand/collapse buttons */ noExpand?: boolean; /** The component to use for the summary, default = `<p>` */ /** The component to use for the summary, default = `<span>` */ component?: string; /** If `true`, shows the full text */ showExpandText?: boolean; Loading
client/src/components/ScrollList/ScrollList.vue +1 −1 Original line number Diff line number Diff line Loading @@ -223,13 +223,13 @@ watch( </slot> <component :is="props.gridView ? 'div' : BListGroup" class="pt-1" :class="{ 'card-list d-flex flex-wrap': props.gridView }"> <!-- Use component wrapper with v-for to provide proper keying while avoiding layout interference --> <component :is="'div'" v-for="(item, index) in items" :key="itemKey(item)" class="" style="display: contents"> <slot name="item" :item="item" :index="index" /> </component> Loading
client/src/components/Workflow/List/WorkflowCardList.vue +1 −1 Original line number Diff line number Diff line Loading @@ -92,7 +92,7 @@ const workflowPublished = ref<InstanceType<typeof WorkflowPublished>>(); </script> <template> <div class="workflow-card-list d-flex flex-wrap overflow-auto"> <div class="workflow-card-list d-flex flex-wrap overflow-auto pt-1"> <WorkflowCard v-for="workflow in workflows" :ref="props.itemRefs[workflow.id]" Loading
client/src/composables/markdown.ts +15 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,16 @@ function addRuleHeadingIncreaseLevel(engine: MarkdownIt, increaseBy: number) { }; } function addRuleNoMargin(engine: MarkdownIt) { engine.renderer.rules.paragraph_open = function (tokens, idx, options, env, self) { const token = tokens[idx]; if (token) { token.attrPush(["style", "margin:0"]); } return self.renderToken(tokens, idx, options); }; } /** * Add a rule that removes newlines after list items. */ Loading Loading @@ -138,6 +148,7 @@ interface UseMarkdownOptions { openLinksInNewPage?: boolean; increaseHeadingLevelBy?: number; removeNewlinesAfterList?: boolean; noMargin?: boolean; } type RawMarkdown = string; Loading @@ -155,6 +166,10 @@ export function useMarkdown(options: UseMarkdownOptions = {}) { addRuleHeadingIncreaseLevel(mdEngine, options.increaseHeadingLevelBy); } if (options.noMargin) { addRuleNoMargin(mdEngine); } if (options.removeNewlinesAfterList) { addRuleRemoveNewlinesAfterList(mdEngine); } Loading