Global HTML files
Hi there. It would be great to have a way of including global HTML + Vue files. I'll drop a few examples why this would be useful:
- If we want to make changes on our header page across all designs. I image having
header.html, and including it with<component src="header.html">. Changes inheader.htmlwould reflect in all designs that include it. - We use a fair bit of custom code. This code exists in all our designs. As you can guess, I imagine having
functions.html, and also including it with<component src="functions.html">. A function defined infunctions.htmlcan then be called throughout the design. I think this would make it much easier to manage several designs.
As for how to implement it, I'm thinking something similar to @include in CSS. Maybe there's some Vue functionality that can be used for this. Alternatively, a custom syntax can be used that's automatically replaced with the source file upon rendering.
In addition, it would be nice to be able to customize these files directly in Sysreptor.
Hope my description is clear. Let me know if there's anything else you need from me!
Hi, thanks for the suggestion. We already got this feature idea from another customer and evaluated it some time ago. A reusable design component library that can be included in every design might certainly improve the maintainability of managing multiple similar designs. However, there are some points that don't integrate well in SysReptor's design architecture:
- design snapshots: SysReptor projects do not directly use global designs. Instead, they create a snapshot of the current design state at the time it was selected. This ensures that changes in the design do not affect projects. This is especially relevant for finished projects from some months/years ago. In our opinion projects should always look the same and render the same PDF regardless if the design was updated or not. A design component library would be a global resource that is used by all designs. Modifications of the included component would result in changes in every design (also for finished projects, which is undesireable).
- import/export/archiving: Projects and designs can be exported and imported between multiple SysReptor instances. We would need to export the used components together with the design. This, however, might result in conflicts when a component with the same name is already present on the other SysReptor instance.
- not self-contained: In our opinion designs should be self-contained and not rely on external or global resources (e.g. included component). This architecture enables design snapshots and export/import.
Because of that, we decided against implementing it. Instead, we recommend to copy/paste the shared code into all designs.
Depending on how similar your designs are and what fields/element they contain, it might be easier to merge them into a single design and control its behavior via variables and if-conditions. For example, we use a single design for regular pentests and re-tests (controlled via boolean field report.is_retest). It's also possible to have one design for multiple languages and do translations of static texts via JS helper functions (e.g. https://docs.sysreptor.com/designer/formatting-utils/#helper-functions-and-variables). I don't know if this is applicable for your use case because it strongly depends on the similarities/differences between the designs and your requirements.
Hi @MWedl, thanks for getting back to me!
I understand that reusable components may introduce some difficulties. However, I do feel that these can be worked around strategically.
design snapshots: SysReptor projects do not directly use global designs. Instead, they create a snapshot of the current design state at the time it was selected. This ensures that changes in the design do not affect projects. This is especially relevant for finished projects from some months/years ago. In our opinion projects should always look the same and render the same PDF regardless if the design was updated or not. A design component library would be a global resource that is used by all designs. Modifications of the included component would result in changes in every design (also for finished projects, which is undesireable).
I appreciate these mechanics, because I agree that existing reports should not automatically be changed when the template is used. I see two ways how this could work:
- Whenever a snapshot is made of a design, snapshots of used global components are also made and saved with the design snapshot. In
<component src="functions.html">, the src would be relative, so the snapshotted component would be referenced rather than the global component. - Whenever a snapshot is made of a design, the
<component src="functions.html">is replaced with the contents of the globalfunctions.htmlfile.functions.htmlis now merged into the snapshot.
import/export/archiving: Projects and designs can be exported and imported between multiple SysReptor instances. We would need to export the used components together with the design. This, however, might result in conflicts when a component with the same name is already present on the other SysReptor instance.
I guess there's a few ways around this one too. I feel the most obvious one is to display a popup in case of a global component conflict, where the user gets to decide between keeping the existing component, overriding the existing component with the new one, of renaming the component to ensure no naming conflicts arise.
not self-contained: In our opinion designs should be self-contained and not rely on external or global resources (e.g. included component). This architecture enables design snapshots and export/import.
I guess the 2nd option of the first section (merging functions.html into the snapshot) would solve these things. While global designs themselves aren't completely self-contained, merging all "external" components into the design when taking a snapshot would ensure that the snapshots are in fact self-contained.
We do already use JS helper functions to do some translations, like for chapter titles and hard-coded table headers. However, designs can also have default values for its fields. These fields contain placeholders, templates, etc. They are somewhat static, but should be easily changed when required, without going into the design (snapshot). Since these texts are configured in the design fields rather than the JS, the only possibility is to create a template per language.
Long story short: I do think that there's ways of achieving this while sticking to what you guys think it important. Then again, I also realize that implementing something like this may require quite some time and effort to get right and I absolutely understand that you may not find it worth the investment. In that case I might take a shot in implementing this as a plugin or something. I haven't looked into Sysreptor plugins yet so we'll see how that goes!
While I've got your attention, I just quickly wanna say that I absolutely love what you guys have built here. I've used PlexTrac with my former employer, but Sysreptor blows PlexTrac away by miles! We are able to create epic reports, exactly how we want them. You guys rock!
Whenever a snapshot is made of a design, the
<component src="functions.html">is replaced with the contents of the globalfunctions.htmlfile.functions.htmlis now merged into the snapshot.
I realize that when doing this, the previewer in the PDF designer for a design template will no longer work, because the design template contain the raw <component />, rather than the replaced source. So, for this to work, the PDF render function must be hooked into to dynamically replace the <component /> tag with the source. I'm building a plugin and I've got the design template to report conversion down. Right now I'm looking to see if there's a way to hook into that PDF render process, but I don't see any obvious ways yet. Should be fine if this were to become a built-in feature though.
I'm not sure if I'm on the right track with this, but wouldn't it resolve all issues if those components are "expanded" (to the full source code) in the moment a new project is created. This would mean that changing a component thereafter, wouldn't affect existing designs, the design would still be self-contained, could be shared, etc.
Kind of! What you're describing is exactly what I proposed so you're for sure on the right track there. That would however not resolve the issue in my last comment. The design template itself would not contain the expanded components, because the component is only expanded when the design template is used to create a report. When developing the design template, the <component /> would be rendered, rather than the component being expanded. That's why the PDF render functionality (or maybe specific to rendering design template previews) should also implement the code to expand the components.