<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Archives des Enterprise content management - dbi Blog</title>
	<atom:link href="https://www.dbi-services.com/blog/category/enterprise-content-management/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.dbi-services.com/blog/category/enterprise-content-management/</link>
	<description></description>
	<lastBuildDate>Thu, 23 Jul 2026 12:01:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/05/cropped-favicon_512x512px-min-32x32.png</url>
	<title>Archives des Enterprise content management - dbi Blog</title>
	<link>https://www.dbi-services.com/blog/category/enterprise-content-management/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>The lifecycle of a document is more important than the document itself</title>
		<link>https://www.dbi-services.com/blog/the-lifecycle-of-a-document-is-more-important-than-the-document-itself/</link>
					<comments>https://www.dbi-services.com/blog/the-lifecycle-of-a-document-is-more-important-than-the-document-itself/#respond</comments>
		
		<dc:creator><![CDATA[Guillaume Meunier]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 12:01:14 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[digitalization]]></category>
		<category><![CDATA[Document Management]]></category>
		<category><![CDATA[Enterprise Content Management]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45658</guid>

					<description><![CDATA[<p>Most ECM projects start with the same question: How are we going to store our documents? It&#8217;s a reasonable question. After all, Enterprise Content Management is often associated with storing files, replacing shared drives, and organizing folders. But does it really matter? No, because the document itself is rarely the real asset. True value lies [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/the-lifecycle-of-a-document-is-more-important-than-the-document-itself/">The lifecycle of a document is more important than the document itself</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Most ECM projects start with the same question:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">How are we going to store our documents?</p>
</blockquote>



<p class="wp-block-paragraph">It&#8217;s a reasonable question. After all, <a href="https://info.aiim.org/what-is-ecm" target="_blank" rel="noreferrer noopener">Enterprise Content Management</a> is often associated with storing files, replacing shared drives, and organizing folders.</p>



<p class="wp-block-paragraph">But does it really matter? No, because the document itself is rarely the real asset.</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img fetchpriority="high" decoding="async" width="300" height="300" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/03/GME_thinking-emoji-300x300.png" alt="Is the document really matter?" class="wp-image-37503" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/03/GME_thinking-emoji-300x300.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/03/GME_thinking-emoji-150x150.png 150w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/03/GME_thinking-emoji-768x768.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/03/GME_thinking-emoji.png 796w" sizes="(max-width: 300px) 100vw, 300px" /></figure>
</div>


<p class="wp-block-paragraph">True value lies in everything that happens before, during, and after a document is created.</p>



<p class="wp-block-paragraph">A contract isn&#8217;t valuable just because it&#8217;s a PDF.</p>



<p class="wp-block-paragraph">It&#8217;s valuable because of the processes it goes through: negotiation, approval, signing, execution, renewal, and eventually expiration.</p>



<p class="wp-block-paragraph">It&#8217;s the lifecycle that creates value, not the file itself.</p>



<h2 id="h-a-document-is-just-a-snapshot" class="wp-block-heading">A document is just a snapshot</h2>



<p class="wp-block-paragraph">Think about an invoice.</p>



<p class="wp-block-paragraph">The invoice itself contains information.</p>



<p class="wp-block-paragraph">But the business process includes much more:</p>



<ul class="wp-block-list">
<li>Who created it?</li>



<li>Has it been approved?</li>



<li>Has it been paid?</li>



<li>Is there a dispute?</li>



<li>Which purchase order does it belong to?</li>



<li>Which supplier issued it?</li>



<li>Is it retained for legal purposes?</li>
</ul>



<p class="wp-block-paragraph">The PDF answers very few of those questions.</p>



<p class="wp-block-paragraph">The lifecycle answers all of them.</p>



<h2 id="h-documents-are-always-moving" class="wp-block-heading">Documents are always moving</h2>



<p class="wp-block-paragraph">One mistake many organizations make is treating documents as static.</p>



<p class="wp-block-paragraph">In reality, every document evolves.</p>



<p class="wp-block-paragraph">A policy may be:</p>



<p class="wp-block-paragraph">Draft → Reviewed → Approved → Published → Updated → Archived → Deleted</p>



<p class="wp-block-paragraph">Every stage has:</p>



<ul class="wp-block-list">
<li>different users</li>



<li>different permissions</li>



<li>different metadata</li>



<li>different business rules</li>
</ul>



<p class="wp-block-paragraph">The lifecycle is dynamic.</p>



<p class="wp-block-paragraph">The document is not.</p>



<h2 id="h-every-stage-has-different-needs" class="wp-block-heading">Every stage has different needs</h2>



<p class="wp-block-paragraph">Consider an employee contract.</p>



<p class="wp-block-paragraph">During drafting:</p>



<ul class="wp-block-list">
<li>HR edits it.</li>



<li>Legal reviews it.</li>
</ul>



<p class="wp-block-paragraph">After signature:</p>



<ul class="wp-block-list">
<li>HR only reads it.</li>



<li>Payroll needs specific information.</li>



<li>Employees access a copy.</li>
</ul>



<p class="wp-block-paragraph">Years later:</p>



<ul class="wp-block-list">
<li>The contract becomes part of an archive.</li>
</ul>



<p class="wp-block-paragraph">The document hasn&#8217;t changed much, but everything around it has.</p>



<h2 id="h-metadata-evolves-too" class="wp-block-heading">Metadata evolves too</h2>



<p class="wp-block-paragraph">Many implementations assume <a href="https://www.dbi-services.com/blog/designing-metadata-cards-that-users-like/" target="_blank" rel="noreferrer noopener">metadata</a> is entered once.</p>



<p class="wp-block-paragraph">In reality, metadata evolves throughout the lifecycle. Even a simple scenario might include:</p>



<p class="wp-block-paragraph">At creation:</p>



<ul class="wp-block-list">
<li>Customer</li>



<li>Supplier</li>



<li>Project</li>
</ul>



<p class="wp-block-paragraph">After approval:</p>



<ul class="wp-block-list">
<li>Approval date</li>



<li>Approver</li>
</ul>



<p class="wp-block-paragraph">At publication:</p>



<ul class="wp-block-list">
<li>Effective date</li>



<li>Version</li>
</ul>



<p class="wp-block-paragraph">After archive:</p>



<ul class="wp-block-list">
<li>Retention category</li>



<li>Destruction date</li>
</ul>



<p class="wp-block-paragraph">For a much more complex case, imagine how the metadata should evolve alongside the business process.</p>



<h2 id="h-automation-should-follow-the-lifecycle" class="wp-block-heading">Automation should follow the lifecycle</h2>



<p class="wp-block-paragraph">Approval is often treated as the end of the process, but in practice it is only one milestone in a much longer journey.</p>



<p class="wp-block-paragraph">Think about everything that could happen automatically.</p>



<p class="wp-block-paragraph">Before approval, you can assign reviewers and validate mandatory fields. </p>



<p class="wp-block-paragraph">After approval, you can notify stakeholders and publish the documentation. </p>



<p class="wp-block-paragraph">While the document is valid, you can monitor deadlines or create associated tasks. </p>



<p class="wp-block-paragraph">When the document expires, it may be useful to send reminders and launch the renewal process. </p>



<p class="wp-block-paragraph">Finally, when the document is obsolete, you can choose to archive or automatically delete it.</p>



<p class="wp-block-paragraph">Automation becomes much more valuable when viewed across the entire lifecycle.</p>



<h2 id="h-search-changes-throughout-the-lifecycle" class="wp-block-heading">Search changes throughout the lifecycle</h2>



<p class="wp-block-paragraph">People don&#8217;t <a href="https://www.dbi-services.com/blog/why-search-is-the-most-underrated-ecm-feature/" target="_blank" rel="noreferrer noopener">search</a> for documents the same way at every stage.</p>



<p class="wp-block-paragraph">While drafting:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Show me my contracts awaiting approval.</p>
</blockquote>



<p class="wp-block-paragraph">Later:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Find the latest signed version.</p>
</blockquote>



<p class="wp-block-paragraph">Years later:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Retrieve every contract with Supplier X from 2021.</p>
</blockquote>



<p class="wp-block-paragraph">The same document.</p>



<p class="wp-block-paragraph">Three completely different search expectations.</p>



<h2 id="h-security-evolves-as-well" class="wp-block-heading">Security evolves as well</h2>



<p class="wp-block-paragraph">Permissions should rarely be static.</p>



<p class="wp-block-paragraph">Draft documents may be confidential.</p>



<p class="wp-block-paragraph">Published procedures should be visible to everyone.</p>



<p class="wp-block-paragraph">Archived contracts should only be accessible to compliance officers.</p>



<p class="wp-block-paragraph">Security should evolve naturally with the document.</p>



<h2 id="h-think-beyond-the-document" class="wp-block-heading">Think beyond the document</h2>



<p class="wp-block-paragraph">Modern ECM systems don&#8217;t simply manage files.</p>



<p class="wp-block-paragraph">They manage information over time.</p>



<p class="wp-block-paragraph">The document becomes one element of a larger ecosystem involving:</p>



<ul class="wp-block-list">
<li>people</li>



<li>workflows</li>



<li>metadata</li>



<li>business objects</li>



<li>automation</li>



<li>retention</li>



<li>AI</li>
</ul>



<p class="wp-block-paragraph">The file itself is almost the least interesting part.</p>



<h2 id="h-final-thoughts" class="wp-block-heading">Final thoughts</h2>



<p class="wp-block-paragraph">A document is created only once.</p>



<p class="wp-block-paragraph">Its lifecycle may last years. That&#8217;s where the real business value lies.</p>



<p class="wp-block-paragraph">Organizations that get the most out of their ECM solution aren&#8217;t the ones that store documents the best.</p>



<p class="wp-block-paragraph">Rather, they are the ones that understand everything that happens before, during, and after those documents exist.</p>



<p class="wp-block-paragraph">After all, it&#8217;s processes, not documents, that create value!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/the-lifecycle-of-a-document-is-more-important-than-the-document-itself/">The lifecycle of a document is more important than the document itself</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/the-lifecycle-of-a-document-is-more-important-than-the-document-itself/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Why search is the most underrated ECM feature</title>
		<link>https://www.dbi-services.com/blog/why-search-is-the-most-underrated-ecm-feature/</link>
					<comments>https://www.dbi-services.com/blog/why-search-is-the-most-underrated-ecm-feature/#respond</comments>
		
		<dc:creator><![CDATA[Guillaume Meunier]]></dc:creator>
		<pubDate>Wed, 15 Jul 2026 12:55:14 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[digitalization]]></category>
		<category><![CDATA[Document Management]]></category>
		<category><![CDATA[M-Files]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45613</guid>

					<description><![CDATA[<p>When organizations evaluate an Enterprise Content Management (ECM) solution, the conversation usually revolves around Artificial Intelligence, workflow automation, and integrations. Yet the feature employees use more than any other is rarely the one showcased in demonstrations or marketing brochures: search. The reality is simple. Most users don&#8217;t spend their days creating workflows or configuring metadata. [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/why-search-is-the-most-underrated-ecm-feature/">Why search is the most underrated ECM feature</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">When organizations evaluate an Enterprise Content Management (ECM) solution, the conversation usually revolves around Artificial Intelligence, workflow automation, and integrations.</p>



<p class="wp-block-paragraph">Yet the feature employees use more than any other is rarely the one showcased in demonstrations or marketing brochures: <strong>search</strong>.</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img decoding="async" width="300" height="300" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/magnifying-glass-1-300x300.png" alt="searching the right info" class="wp-image-45622" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/magnifying-glass-1-300x300.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/magnifying-glass-1-150x150.png 150w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/magnifying-glass-1-768x768.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/magnifying-glass-1.png 796w" sizes="(max-width: 300px) 100vw, 300px" /></figure>
</div>


<p class="wp-block-paragraph">The reality is simple. Most users don&#8217;t spend their days creating workflows or configuring metadata. They spend it looking for information.</p>



<p class="wp-block-paragraph">Every unsuccessful search comes at a cost!</p>



<h2 id="h-search-happens-more-often-than-you-think" class="wp-block-heading">Search happens more often than you think</h2>



<p class="wp-block-paragraph">Think about your workday.</p>



<p class="wp-block-paragraph">How many documents do you create?</p>



<p class="wp-block-paragraph">Maybe a few.</p>



<p class="wp-block-paragraph">How many do you approve?</p>



<p class="wp-block-paragraph">Perhaps a few more.</p>



<p class="wp-block-paragraph">Now, ask yourself a different question: How many times do you search for information?</p>



<p class="wp-block-paragraph">Procedures, invoices, contracts, customer communications&#8230;</p>



<p class="wp-block-paragraph">For most employees, searching is the most common interaction with an ECM system by far.</p>



<p class="wp-block-paragraph">This means that even minor improvements to the search function can significantly impact productivity.</p>



<h2 id="h-finding-a-document-is-only-half-the-problem" class="wp-block-heading">Finding a document is only half the problem</h2>



<p class="wp-block-paragraph">Many ECM vendors claim they can find any document in seconds.</p>



<p class="wp-block-paragraph">That&#8217;s great, but it&#8217;s often not enough.</p>



<p class="wp-block-paragraph">Imagine a customer calls about an invoice. You know the supplier, but not the invoice number.</p>



<p class="wp-block-paragraph">A good ECM lets you find the document in seconds by searching the supplier, project, purchase order, or even the contract linked to it.</p>



<p class="wp-block-paragraph">A poor search experience forces you to browse folders, ask colleagues, or search through emails.</p>



<p class="wp-block-paragraph">An effective search is about relevance, not just speed.</p>



<h2 id="h-search-starts-long-before-someone-types-a-keyword" class="wp-block-heading">Search starts long before someone types a keyword</h2>



<p class="wp-block-paragraph">Many organizations try to improve their search function by tweaking the search engine.</p>



<p class="wp-block-paragraph">In reality, a good search starts much earlier.</p>



<p class="wp-block-paragraph">It begins with:</p>



<ul class="wp-block-list">
<li>meaningful metadata</li>



<li>consistent naming conventions</li>



<li>well-designed object relationships</li>



<li>document classifications</li>



<li>quality-controlled information</li>
</ul>



<p class="wp-block-paragraph">Poor information management cannot be fixed with search alone.</p>



<p class="wp-block-paragraph">Even the most advanced search engine will struggle to deliver useful results if the metadata is inconsistent or incomplete.</p>



<h2 id="h-search-should-reduce-decisions" class="wp-block-heading">Search should reduce decisions</h2>



<p class="wp-block-paragraph">A good search experience should minimize the amount of thought required of users.</p>



<p class="wp-block-paragraph">Instead of asking:</p>



<p class="wp-block-paragraph">&#8220;What was the exact document name?&#8221;</p>



<p class="wp-block-paragraph">Users should be able to search naturally:</p>



<ul class="wp-block-list">
<li>customer name</li>



<li>supplier</li>



<li>project</li>



<li>Invoice number</li>



<li>Contract type</li>



<li>Date</li>



<li>Keywords</li>
</ul>



<p class="wp-block-paragraph">The system should handle the complexities.</p>



<p class="wp-block-paragraph">Users shouldn&#8217;t need to understand how the information is stored.</p>



<h2 id="h-what-about-ai" class="wp-block-heading">What about AI?</h2>



<p class="wp-block-paragraph">Generative AI doesn&#8217;t replace search, it changes users&#8217; expectations of search.</p>



<p class="wp-block-paragraph">Now users want to be able to ask questions like:</p>



<p class="wp-block-paragraph">&#8220;Show me all contracts that expire next quarter.&#8221;</p>



<p class="wp-block-paragraph">Or:</p>



<p class="wp-block-paragraph">&#8220;Find the latest approved procedure for handling customer complaints.&#8221;</p>



<p class="wp-block-paragraph">Behind these simple questions lies something much less glamorous: reliable metadata.</p>



<p class="wp-block-paragraph">Without it, AI cannot consistently provide trustworthy answers.</p>



<p class="wp-block-paragraph">In many ways, AI has made search even more important.</p>



<h2 id="h-search-is-a-user-experience-feature" class="wp-block-heading">Search is a user experience feature</h2>



<p class="wp-block-paragraph">When discussing user adoption, project teams often focus on training.</p>



<p class="wp-block-paragraph">Training certainly matters.</p>



<p class="wp-block-paragraph">However, the user experience during searches is also important.</p>



<p class="wp-block-paragraph">If employees consistently find what they need in seconds, their confidence in the system grows.</p>



<p class="wp-block-paragraph">However, if they repeatedly fail to find information, they&#8217;ll quickly return to shared drives, email folders, or ask colleagues for help.</p>



<p class="wp-block-paragraph">The quality of the search function shapes the perception of the entire enterprise content management (ECM) solution.</p>



<h2 id="h-search-is-a-business-capability" class="wp-block-heading">Search is a business capability</h2>



<p class="wp-block-paragraph">A good search is about more than just saving a few minutes.</p>



<ul class="wp-block-list">
<li>It enables better decision-making.</li>



<li>It prevents duplicate work.</li>



<li>It improves compliance.</li>



<li>It accelerates customer service.</li>



<li>It helps preserve organizational knowledge.</li>
</ul>



<p class="wp-block-paragraph">The value of an ECM system isn&#8217;t measured by how many documents it stores.</p>



<p class="wp-block-paragraph">Rather, it&#8217;s measured by how effectively those documents can be found and used.</p>



<h2 id="h-final-words" class="wp-block-heading">Final words</h2>



<p class="wp-block-paragraph">Search rarely appears as the headline feature in product demonstrations because every ECM platform offers some form of search.</p>



<p class="wp-block-paragraph">The real difference isn&#8217;t whether a system can search, it&#8217;s <strong>how effectively users can find the right information when they need it.</strong></p>



<p class="wp-block-paragraph">A successful ECM implementation isn&#8217;t one where information is simply stored.</p>



<p class="wp-block-paragraph">Rather, it&#8217;s one where information is found effortlessly, trusted confidently, and reused effectively.</p>



<p class="wp-block-paragraph">After all, a document that can&#8217;t be found might as well not exist.</p>



<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/why-search-is-the-most-underrated-ecm-feature/">Why search is the most underrated ECM feature</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/why-search-is-the-most-underrated-ecm-feature/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Designing metadata cards that users like</title>
		<link>https://www.dbi-services.com/blog/designing-metadata-cards-that-users-like/</link>
					<comments>https://www.dbi-services.com/blog/designing-metadata-cards-that-users-like/#respond</comments>
		
		<dc:creator><![CDATA[Guillaume Meunier]]></dc:creator>
		<pubDate>Thu, 09 Jul 2026 06:47:27 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[digitalization]]></category>
		<category><![CDATA[Enterprise Content Management]]></category>
		<category><![CDATA[M-Files]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45510</guid>

					<description><![CDATA[<p>Over the past few weeks, I’ve addressed philosophical questions related to enterprise content management (ECM), such as &#8220;What should be done?&#8221; and &#8220;Why?&#8221; Now, it’s time to focus on the “how.” When discussing user adoption of M-Files, the conversation often centers on training, change management, and automation. While these aspects are important, another factor immediately [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/designing-metadata-cards-that-users-like/">Designing metadata cards that users like</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Over the past few weeks, I’ve addressed philosophical questions related to enterprise content management (ECM), such as &#8220;What should be done?&#8221; and &#8220;Why?&#8221; Now, it’s time to focus on the “how.” </p>



<p class="wp-block-paragraph">When discussing user adoption of M-Files, the conversation often centers on training, change management, and automation. While these aspects are important, another factor immediately impacts the user experience: the Metadata Card.</p>



<p class="wp-block-paragraph">A poorly designed Metadata Card can overwhelm users with unnecessary fields and irrelevant questions, making creating a document feel like filling out a tax form. Conversely, a well-designed Metadata Card naturally guides users through the process by displaying only the necessary information.</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img decoding="async" width="300" height="300" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/true-300x300.png" alt="" class="wp-image-45533" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/true-300x300.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/true-150x150.png 150w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/true-768x768.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/true.png 796w" sizes="(max-width: 300px) 100vw, 300px" /></figure>
</div>


<p class="wp-block-paragraph">The goal is not to collect as much metadata as possible but rather to collect the right metadata at the right time.</p>



<p class="wp-block-paragraph">Just a reminder that in <a href="https://www.m-files.com" target="_blank" rel="noreferrer noopener">M-Files</a>, a metadata card is the panel that displays and allows users to edit the metadata properties of an object. It is an essential component of the tool.</p>



<h2 id="h-start-with-the-user-journey" class="wp-block-heading">Start with the user journey</h2>



<p class="wp-block-paragraph">Before creating properties or configuring rules, ask a simple question:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">What information does the user actually know at this stage?</p>
</blockquote>



<p class="wp-block-paragraph">Consider an invoice.</p>



<p class="wp-block-paragraph">At creation, the user probably knows:</p>



<ul class="wp-block-list">
<li>Supplier</li>



<li>Invoice number</li>



<li>Invoice date</li>



<li>Amount</li>
</ul>



<p class="wp-block-paragraph">They probably don&#8217;t know:</p>



<ul class="wp-block-list">
<li>Approval status</li>



<li>Payment date</li>



<li>Accounting reference</li>



<li>Archive classification</li>
</ul>



<p class="wp-block-paragraph">Those properties should appear only when they become relevant.</p>



<p class="wp-block-paragraph">Metadata Card should evolve with the document lifecycle rather than exposing every possible property from the beginning.</p>



<h2 id="h-hide-what-isn-t-needed" class="wp-block-heading">Hide what isn&#8217;t needed</h2>



<p class="wp-block-paragraph">One of the most effective improvements is dynamic property visibility.</p>



<p class="wp-block-paragraph">Rather than displaying every property permanently, configure the card so that properties only appear when certain conditions are met.</p>



<p class="wp-block-paragraph">For example:</p>



<ul class="wp-block-list">
<li>If the document class is &#8220;Contract&#8221;, display the contract expiration date.</li>



<li>If the supplier is external, display vendor-specific properties.</li>



<li>If the document is confidential, display the security classification section.</li>



<li>If the document enters the approval workflow, display approval-related properties.</li>
</ul>



<p class="wp-block-paragraph">This approach reduces visual clutter and helps users focus on the task at hand.</p>



<h2 id="h-make-properties-mandatory-only-when-necessary" class="wp-block-heading">Make properties mandatory only when necessary</h2>



<p class="wp-block-paragraph">One common mistake is making too many properties mandatory.</p>



<p class="wp-block-paragraph">Although mandatory properties can be useful, they should only be used when appropriate.</p>



<p class="wp-block-paragraph">For example:</p>



<p class="wp-block-paragraph">The &#8220;termination date&#8221; property should not be mandatory when creating a new employee contract. This property only becomes relevant if the employee leaves the company.</p>



<p class="wp-block-paragraph">Conditional mandatory properties allow for validation without frustrating users.</p>



<p class="wp-block-paragraph">Rather than forcing users to enter placeholder values just to save the document, only ask for this information when it is required by the business process.</p>



<h2 id="h-group-related-information" class="wp-block-heading">Group related information</h2>



<p class="wp-block-paragraph">Metadata cards are easier to navigate when related properties are grouped together.</p>



<p class="wp-block-paragraph">Instead of a long list of unrelated fields, organize them into logical sections.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="428" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/OrgsnizeMDC-1024x428.jpg" alt="" class="wp-image-45523" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/OrgsnizeMDC-1024x428.jpg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/OrgsnizeMDC-300x125.jpg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/OrgsnizeMDC-768x321.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/OrgsnizeMDC-1536x642.jpg 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/07/OrgsnizeMDC.jpg 1652w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Same properties but on the right we organized them</figcaption></figure>
</div>


<p class="wp-block-paragraph">Users scan information much faster when it is visually organized.</p>



<p class="wp-block-paragraph">Additionally, sections that are not needed at a given stage can be hidden or collapsed.</p>



<h2 id="h-reduce-decisions" class="wp-block-heading">Reduce decisions</h2>



<p class="wp-block-paragraph">Every visible property asks the user to make a decision.</p>



<p class="wp-block-paragraph">Should I fill this in?</p>



<p class="wp-block-paragraph">Does this apply to my document?</p>



<p class="wp-block-paragraph">What does this property even mean?</p>



<p class="wp-block-paragraph">A good metadata card minimizes these decisions.</p>



<p class="wp-block-paragraph">It is good practice to use:</p>



<ul class="wp-block-list">
<li>Automatic values</li>



<li>Default values</li>



<li>Value lists</li>



<li>Metadata inheritance</li>



<li>Calculated properties</li>
</ul>



<p class="wp-block-paragraph">The fewer decisions users have to make, the faster and more accurately they can classify documents.</p>



<h2 id="h-avoid-the-everything-might-be-useful" class="wp-block-heading">Avoid the &#8220;Everything might be useful&#8221;</h2>



<p class="wp-block-paragraph">One of the biggest design mistakes is trying to satisfy every department.</p>



<p class="wp-block-paragraph">For instance, the Human Resources department requires three properties, the Legal department requests five more, the Finance department submits a request for four additional fields, and finally, the Compliance department adds another six.</p>



<p class="wp-block-paragraph">After a few workshops, the metadata card ends up with thirty or forty properties.</p>



<p class="wp-block-paragraph">Technically, everything is possible.</p>



<p class="wp-block-paragraph">Practically, nobody enjoys using it.</p>



<p class="wp-block-paragraph">Whenever a new property is requested, ask:</p>



<ul class="wp-block-list">
<li>Who will maintain it?</li>



<li>Who actually uses it?</li>



<li>What business process depends on it?</li>



<li>What happens if it remains empty?</li>
</ul>



<p class="wp-block-paragraph">If there isn&#8217;t a clear answer, then the property probably isn&#8217;t necessary.</p>



<h2 id="h-design-for-the-common-case" class="wp-block-heading">Design for the common case</h2>



<p class="wp-block-paragraph">Most users perform the same actions repeatedly.<br><br>Optimize the metadata card for 80% of documents rather than exceptional cases.<br><br>Advanced scenarios can reveal additional properties as needed.<br><br>Simple cases should remain simple.</p>



<h2 id="h-think-like-a-product-designer" class="wp-block-heading">Think like a product designer</h2>



<p class="wp-block-paragraph">Administrators often focus on configuration, whereas it is the users who interact with the interface.</p>



<p class="wp-block-paragraph">Therefore, it is important to keep in mind that every additional property increases cognitive load.</p>



<p class="wp-block-paragraph">Similarly, every unnecessary required field creates friction.</p>



<p class="wp-block-paragraph">Conversely, every hidden property reduces complexity.</p>



<p class="wp-block-paragraph">A well-designed metadata card improves not only data quality but also the user experience of the entire M-Files system.</p>



<h2 id="h-conclusion" class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">Metadata is one of M-Files&#8217; greatest strengths, but only if users provide it.</p>



<p class="wp-block-paragraph">The best metadata card isn&#8217;t the one that captures the most information.</p>



<p class="wp-block-paragraph">Rather, it&#8217;s the one that asks the fewest questions while still collecting everything the business needs.</p>



<p class="wp-block-paragraph">When users feel that the system understands their tasks instead of getting in their way, they will naturally adopt it.</p>



<p class="wp-block-paragraph">Sometimes improving user satisfaction isn&#8217;t about adding new functionality; it&#8217;s about designing a better metadata card.</p>



<p class="wp-block-paragraph">Whether you&#8217;re planning a new M-Files implementation or looking to improve an existing one, we can help you design a solution that is efficient, user-friendly, and aligned with your business needs. Feel free to <a href="https://www.dbi-services.com/technologies/m-files-document-management-solutions/">contact us</a> to discuss your project.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/designing-metadata-cards-that-users-like/">Designing metadata cards that users like</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/designing-metadata-cards-that-users-like/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>M-Files Outlook Pro add-in configuration</title>
		<link>https://www.dbi-services.com/blog/m-files-outlook-pro-add-in-configuration/</link>
					<comments>https://www.dbi-services.com/blog/m-files-outlook-pro-add-in-configuration/#respond</comments>
		
		<dc:creator><![CDATA[Andreas Trefzer]]></dc:creator>
		<pubDate>Tue, 30 Jun 2026 16:04:00 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[Non classifié(e)]]></category>
		<category><![CDATA[M-Files]]></category>
		<category><![CDATA[Microsoft]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45425</guid>

					<description><![CDATA[<p>In this blog post, I will outline the steps required to enable and configure the M-Files Outlook Pro add-in. This includes configuring Microsoft Outlook rules to automate email handling. It took me some time to configure the rules, as they were not working as I expected. I hope this blog helps others save time. Installation [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-outlook-pro-add-in-configuration/">M-Files Outlook Pro add-in configuration</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In this blog post, I will outline the steps required to enable and configure the M-Files Outlook Pro add-in. This includes configuring Microsoft Outlook rules to automate email handling. It took me some time to configure the rules, as they were not working as I expected. I hope this blog helps others save time.</p>



<h2 id="h-installation" class="wp-block-heading">Installation</h2>



<p class="wp-block-paragraph">The installation is very straight forward and well documented, it can take some time for the creation of the necessary self signed certificated for the Microsoft Azure Application. In addition, you must ensure that you have management access to the Microsoft Azure Admin Centre or an admin aside to perform the required steps</p>



<p class="wp-block-paragraph">I will. not go through each step in detail, but I will highlight important steps from my point of view. The step by step documentation can be found on the <a data-type="link" data-id="https://catalog.m-files.com/shop/m-files-for-outlook-pro/" href="https://catalog.m-files.com/shop/m-files-for-outlook-pro/" target="_blank" rel="noreferrer noopener">M-Files web page for Integrations</a>.</p>



<p class="wp-block-paragraph"><strong><span style="text-decoration: underline">Important steps:</span></strong></p>



<ul class="wp-block-list">
<li>Allow third-party cookies for Outlook Web.<br>https://[*.]office365.com<br>https://[*.]office.com</li>



<li>Ensure that the lins below not blocked by the firewall.<br><a href="https://mfnewoutlookaddinprod.m-files.com">https://mfnewoutlookaddinprod.m-files.com </a><br><a href="https://login.microsoftonline.com/common">https://login.microsoftonline.com/common </a><br><a href="https://login.m-files.com/">https://login.m-files.com/</a></li>



<li>Create a self signed certificate and convert them to be able to configure the M-Files Vault Application.</li>



<li>Create and configure the Application in Azure, according the M-Files documentation.</li>



<li>Installation and configure the M-Files Vault Application, just follow the M-Files documnetation.</li>



<li>Install or deploy the M-Files for Outlook add-in. It is a certified Microsoft application. It can be installed individually or deployed to a specific group of users. This is the standard Microsoft process.<br></li>
</ul>



<p class="wp-block-paragraph"><strong><span style="text-decoration: underline">Create a self signed certificate for use in a cloud setup </span></strong></p>



<p class="wp-block-paragraph">Open PowerShell with administrative access and use the command below.</p>



<pre class="wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-993212c8ced4a58198a258f4546fb223"><code>$certname = "{certificateName}"    ## Replace {certificateName}
$cert = New-SelfSignedCertificate -Subject "CN=$certname" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256

Export-Certificate -Cert $cert -FilePath "C:\Users\admin\Desktop\$certname.cer"   ## Specify your preferred location

$mypwd = ConvertTo-SecureString -String "{myPassword}" -Force -AsPlainText  ## Replace {myPassword}

Export-PfxCertificate -Cert $cert -FilePath "C:\Users\admin\Desktop\$certname.pfx" -Password $mypwd   ## Specify your preferred location</code></pre>



<p class="wp-block-paragraph">In case you get an execution error from PowerShell, you can use the command below to allow the execution</p>



<pre class="wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-e819ee148d2e9cc1a1af76cabdf67a72"><code>Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force</code></pre>



<p class="wp-block-paragraph">If everything worked as expected you have files as in the example below.</p>



<pre class="wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-043aaeae0c63f259e1bce9223ca937a6"><code>Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        29/06/2026     08:18            772 testcert.cer
-a----        29/06/2026     08:20           2644 testcert.pfx</code></pre>



<p class="wp-block-paragraph">To convert the certificates, you will need to use OpenSSH and Cygwin. M-Files strongly recommends using Cygwin. I encountered issues when I did not use Cygwin and it did not work.<br>Conversion is required in order to configure the certificate within the M-Files Vault application.</p>



<p class="wp-block-paragraph">After the installation of <a href="https://www.cygwin.com" id="https://www.cygwin.com">Cygwin</a> the command below must be executed in a Cygwin command window.</p>



<pre class="wp-block-code has-white-color has-black-background-color has-text-color has-background has-link-color wp-elements-72b175285d06ceb86e15f5c96e94f249"><code>openssl pkcs12 -in MyCert.pfx -out MyCert.pem -nokeys<br><br>openssl pkcs12 -in MyCert.pfx -out MyCert.key -nocerts<br><br>openssl rsa -in MyCert.key -out MyCert_encrypted.key -aes256</code></pre>



<h2 id="h-configure-the-outlook-and-m-files-rules" class="wp-block-heading">Configure the Outlook and M-Files rules</h2>



<p class="wp-block-paragraph" id="h-configure-the-outlook-and-m-files-rules">You can use the Outlook and M-Files rules to automatically save received emails to the M-Files system. It is important to understand how each rule works within the M-Files Outlook add-in. This differs from creating an object in M-Files, where the workflow and required state must be explicitly defined.</p>



<p class="wp-block-paragraph">Open the M-Files Outlook Add-In in Outlook and navigate to &#8220;Manage folder rules.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="658" height="504" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-50.png" alt="M-Fikles Outlook add-in rule" class="wp-image-45459" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-50.png 658w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-50-300x230.png 300w" sizes="auto, (max-width: 658px) 100vw, 658px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="647" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-52-1024x647.png" alt="Outlook rule" class="wp-image-45461" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-52-1024x647.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-52-300x190.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-52-768x486.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-52-1536x971.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-52.png 1762w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">The screenshot below shows the configuration of the Outlook folder &#8220;Firma A &#8211; Projekt A&#8221;, which will be imported automatically and assigned to the M-Files class &#8216;Email Import&#8217;. Additionally, the &#8220;Email Import Validation&#8221; workflow with the state &#8220;Import prüfen&#8221; is assigned.<br>If the workflow is not defined in the rule, it will not be assigned as expected. As we know, when a new object is created in M-Files, the workflow of the class is used automatically.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="594" height="1024" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-51-594x1024.png" alt="" class="wp-image-45460" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-51-594x1024.png 594w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-51-174x300.png 174w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/image-51.png 640w" sizes="auto, (max-width: 594px) 100vw, 594px" /></figure>



<h2 id="h-conclusion" class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">In order to automate the process of moving incoming emails into M-Files, two steps are required. First, define the usual Outlook rule, then create a rule in the M-Files Outlook add-in, as explained above.</p>



<p class="wp-block-paragraph">Don&#8217;t hesitate to get in touch with <a href="https://www.dbi-services.com" target="_blank" rel="noreferrer noopener">us</a> or directly with <a href="https://www.linkedin.com/in/andreas-trefzer-120282b/" target="_blank" rel="noreferrer noopener">me</a> if you have any more questions or need support with implementation.</p>



<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-outlook-pro-add-in-configuration/">M-Files Outlook Pro add-in configuration</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/m-files-outlook-pro-add-in-configuration/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>M-Files BD &#8211; Putting it together with the Visual Designer</title>
		<link>https://www.dbi-services.com/blog/m-files-bd-putting-it-together-with-the-visual-designer/</link>
					<comments>https://www.dbi-services.com/blog/m-files-bd-putting-it-together-with-the-visual-designer/#respond</comments>
		
		<dc:creator><![CDATA[Morgan Patou]]></dc:creator>
		<pubDate>Mon, 29 Jun 2026 20:19:33 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[area]]></category>
		<category><![CDATA[Business Dashboard]]></category>
		<category><![CDATA[donut]]></category>
		<category><![CDATA[Gauge]]></category>
		<category><![CDATA[JSON Editor]]></category>
		<category><![CDATA[kpiNumber]]></category>
		<category><![CDATA[M-Files]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[Visual Designer]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45433</guid>

					<description><![CDATA[<p>After several posts of theory, it&#8217;s time to build something. In this post, I will walk you through a Visual Designer tutorial to create a complete Contracts dashboard on the M-Files Sample Vault. Therefore, no JSON editing is required at all. The Visual Designer is the primary authoring path for most administrators. Power users who [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-bd-putting-it-together-with-the-visual-designer/">M-Files BD &#8211; Putting it together with the Visual Designer</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">After several posts of theory, it&#8217;s time to build something. In this post, I will walk you through a Visual Designer tutorial to create a complete Contracts dashboard on the M-Files Sample Vault. Therefore, no JSON editing is required at all. The Visual Designer is the primary authoring path for most administrators. Power users who prefer hand-editing JSON can write directly in the JSON editor (toggle to switch in the top bar), but this post focuses on the visual approach where you build dashboards by clicking and filling forms.</p>



<p class="wp-block-paragraph">I picked the <strong>Sample Vault</strong> because it is the one that gets shipped when you are installing M-Files in evaluation mode and it contains some sample data, as its name suggests&#8230; Please note that since it is a rather old vault, data inside was created somewhere between 2004 and 2012. Therefore, in this blog, I will go back in time (yes, I can!) and consider that &#8220;today&#8221; is actually the &#8220;01-Nov-2011&#8221; (<strong>2011-11-01</strong>). In a real vault, you would use the dateToken <strong>&#8220;@today&#8221;</strong> instead, but for this blog, to allow you to reproduce the steps below, I chose that specific date since it gives interesting data to visualize.</p>



<h2 id="h-1-what-i-am-going-to-build" class="wp-block-heading">1. What I am going to build</h2>



<p class="wp-block-paragraph">The target dashboard has eight widgets:</p>



<ul class="wp-block-list">
<li>Four KPI tiles in a row at the top: Active Contracts, Expired Contracts, Contract Expiry &lt; 180d, No expiry date.</li>



<li>One donut: Contracts by agreement type.</li>



<li>One gauge (date-mode): days until the earliest/next contract expiry.</li>



<li>One area: contract expiry per year and per agreement type.</li>



<li>One table: all expired contracts (for review or sales purpose).</li>
</ul>



<p class="wp-block-paragraph">This layout fills the right pane with a clean &#8220;summary at the top, distribution in the middle, action items at the bottom&#8221; reading order.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fa2dda&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fa2dda" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2560" height="2011" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.1-scaled.png" alt="Visual Designer tutorial end result" class="wp-image-45434" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.1-scaled.png 2560w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.1-300x236.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.1-1024x804.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.1-768x603.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.1-1536x1206.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.1-2048x1609.png 2048w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-2-creating-a-new-dashboard" class="wp-block-heading">2. Creating a new dashboard</h2>



<p class="wp-block-paragraph">The dashboard management is done on the M-Files Admin UI. To access it, open <strong>M-Files Admin</strong> -&gt; <strong>Configurations</strong> -&gt; <strong>Other Applications</strong> -&gt; <strong>dbi services Business Dashboard</strong> -&gt; <strong>Dashboard</strong> tab. Then click on the <strong><em>Add New</em></strong> button. The editor opens, by default in Visual mode with an empty canvas and the Dashboard Settings panel on the right:</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fa5690&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fa5690" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2370" height="1668" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.2.png" alt="Visual Designer default look&amp;feel" class="wp-image-45435" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.2.png 2370w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.2-300x211.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.2-1024x721.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.2-768x541.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.2-1536x1081.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.2-2048x1441.png 2048w" sizes="auto, (max-width: 2370px) 100vw, 2370px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-3-dashboard-settings" class="wp-block-heading">3. Dashboard Settings</h2>



<p class="wp-block-paragraph">Before adding widgets, let&#8217;s configure the dashboard-level fields in the right panel. The below assumes you never updated the default values. If you would like to update the defaults so all future dashboards have your own, you can do it in the <strong>Configuration</strong> tab.</p>



<ul class="wp-block-list">
<li><strong>Name</strong>: <strong><em>Contracts Snapshot (01-Nov-2011)</em></strong>.</li>



<li><strong>Description (optional)</strong>: <strong><em>Quick view of contracts: active, expiring, distribution.</em></strong>.</li>



<li><strong>Auto-refresh enabled</strong>: <strong><em>No</em></strong> (leave off for now, you can flip it on later if needed).</li>



<li><strong>User can toggle</strong>: <strong><em>Yes</em></strong> (users can enable the auto-refresh).</li>



<li><strong>Export to PDF enabled</strong>: <strong><em>Yes</em></strong>.</li>



<li><strong>Export to CSV enabled</strong>: <strong><em>Yes</em></strong>.</li>



<li><strong>Drill-through enabled</strong>: <strong><em>Yes</em></strong> (this is what makes the chart elements clickable and it displays details about the matching objects).</li>



<li>Leave the rest as default. There are enough query results to fetch all details, each user sees only the objects their M-Files ACL allows, etc.</li>
</ul>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fa6da1&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fa6da1" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2366" height="1666" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.3.png" alt="Updating the dashboard parameters in the Visual Designer" class="wp-image-45436" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.3.png 2366w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.3-300x211.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.3-1024x721.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.3-768x541.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.3-1536x1082.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.3-2048x1442.png 2048w" sizes="auto, (max-width: 2366px) 100vw, 2366px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-4-the-first-kpi-tile-active-contracts" class="wp-block-heading">4. The first KPI tile: Active Contracts</h2>



<p class="wp-block-paragraph">Click on the <strong><em>+ Add Widget</em></strong> button in the footer. A blank tile appears on the canvas and the right panel switches to the widget config.</p>



<p class="wp-block-paragraph">First, we set the widget basic details:</p>



<ul class="wp-block-list">
<li><strong>Widget Title</strong>: <strong><em>Active Contracts</em></strong>.</li>



<li><strong>Description (optional)</strong>: leave empty.</li>



<li><strong>Widget Type</strong>: <strong><em>KPI Number</em></strong>.</li>



<li><strong>Col Span</strong>: <strong><em>3</em></strong>.</li>



<li><strong>Row Span</strong>: <strong><em>1</em></strong>.</li>
</ul>



<p class="wp-block-paragraph">Then, we need to configure the source of the data we want to see:</p>



<ul class="wp-block-list">
<li><strong>Object Type(s)</strong>: <strong><em>Document</em></strong> (dropdown shows the vault&#8217;s object types).</li>



<li><strong>Class (optional)</strong>: <strong><em>Contract or Agreement</em></strong> (automatically populated after selecting an object type).</li>



<li><strong>Aggregation Type</strong>: <strong><em>summary</em></strong> (already set automatically since it&#8217;s the only one supported by kpiNumber).</li>
</ul>



<p class="wp-block-paragraph">Optionally, we can configure one or more filters. Here, since we want to see only active contracts (i.e. that have an effective-through date superior or equal to today), then we need to apply a certain filter. Click on the <strong><em>+ Add Filter</em></strong> button and a row appears:</p>



<ul class="wp-block-list">
<li><strong>Property</strong>: <strong><em>Effective through (date)</em></strong> (from the property dropdown, the &#8220;(date)&#8221; is the data-type that is shown but it&#8217;s not part of the property name).</li>



<li><strong>Operator</strong>: <strong><em>greater than or equal (&gt;=)</em></strong>.</li>



<li><strong>Value type</strong>: <strong><em>dateToken</em></strong>.</li>



<li><strong>Value</strong>: <strong><em>2011-11-01</em></strong> (instead of &#8220;@today&#8221; in a real vault).</li>
</ul>



<p class="wp-block-paragraph">Finally, we define the aggregation (i.e. what to do with the results obtained) as well as the display section, which are optional graphical/rendering details:</p>



<ul class="wp-block-list">
<li><strong>Reducer</strong>: <strong><em>count</em></strong> (default).</li>



<li><strong>Drill-through Columns (comma-sep)</strong>: <strong><em>Agreement type, Effective through</em></strong> (the additional columns to add to table lists or drill-through details tables).</li>



<li><strong>Display Unit</strong>: <strong><em>contracts</em></strong>.</li>
</ul>



<p class="wp-block-paragraph">To validate that the configuration is correct, you can click on the <strong><em>Test Widget</em></strong> button in the footer. The Test Results panel expands on the right side, and shows a green <strong><em>OK</em></strong>, which confirms the definition is correct. So far, so good.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fa7919&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fa7919" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2368" height="1664" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.4.png" alt="Testing a first widget in Visual Designer" class="wp-image-45437" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.4.png 2368w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.4-300x211.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.4-1024x720.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.4-768x540.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.4-1536x1079.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.4-2048x1439.png 2048w" sizes="auto, (max-width: 2368px) 100vw, 2368px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-5-the-other-three-kpi-tiles" class="wp-block-heading">5. The other three KPI tiles</h2>



<p class="wp-block-paragraph">The next three KPIs follow the same pattern as the first one, with different filters.</p>



<h3 id="h-5-1-expired-contracts" class="wp-block-heading">5.1. Expired Contracts</h3>



<p class="wp-block-paragraph">With the 1st widget selected, click on the <strong><em>Clone Widget</em></strong> button. A new tile appears next to the first one, with exactly the same content. Simply update these fields:</p>



<ul class="wp-block-list">
<li><strong>Widget Title</strong>: <strong><em>Expired Contracts</em></strong>.</li>



<li><strong>Operator</strong> (Filter): <strong><em>less than (&lt;)</em></strong>.</li>
</ul>



<p class="wp-block-paragraph">Click on the <strong><em>+ Add Threshold</em></strong> button and a row appears:</p>



<ul class="wp-block-list">
<li><strong>Value</strong> (Threshold): <strong><em>1</em></strong> (any value equal or above 1 will match).</li>



<li><strong>Color</strong> (Threshold): <strong><em>red</em></strong> or <strong><em>#e74c3c</em></strong> (color used if above value is reached).</li>
</ul>



<h3 id="h-5-2-expiring-in-next-180-days" class="wp-block-heading">5.2. Expiring in next 180 days</h3>



<p class="wp-block-paragraph">Click on the <strong><em>Clone Widget</em></strong> button again:</p>



<ul class="wp-block-list">
<li><strong>Widget Title</strong>: <strong><em>Contract Expiry &lt; 180d</em></strong>.</li>



<li><strong>Operator</strong> (Filter): <strong><em>between (from,to)</em></strong></li>



<li><strong>Value</strong> (Filter): <strong><em>2011-11-01, 2011-11-01+180d</em></strong> (instead of &#8220;@today, @today+180d&#8221; in a real vault).</li>



<li><strong>Color</strong> (Threshold): <strong><em>orange</em></strong> or <strong><em>#f39c12</em></strong> (update the existing threshold and keep the value as 1).</li>
</ul>



<h3 id="h-5-3-no-expiry-date" class="wp-block-heading">5.3. No expiry date</h3>



<p class="wp-block-paragraph">Click on the <strong><em>Clone Widget</em></strong> button again:</p>



<ul class="wp-block-list">
<li><strong>Widget Title</strong>: <strong><em>No expiry date</em></strong>.</li>



<li><strong>Operator</strong> (Filter): <strong><em>is empty (incl. absent)</em></strong> (no value field for this operator).</li>
</ul>



<p class="wp-block-paragraph">Click on the <strong><em>+ Add Threshold</em></strong> button and a second row appears (keep the other one with 1-orange):</p>



<ul class="wp-block-list">
<li><strong>Value</strong> (Threshold): <strong><em>0</em></strong> (any value equal or above 0 but below 1 (c.f. other threshold) will match. i.e. only valid if equal to 0).</li>



<li><strong>Color</strong> (Threshold): <strong><em>green</em></strong> or <strong><em>#27ae60</em></strong> (color used if above value is reached).</li>
</ul>



<p class="wp-block-paragraph">At this point the canvas shows four KPI tiles. They each have <strong><em>colSpan: 3</em></strong>, so they sit nicely in a row of four totalling 12 (full width of the dashboard). You can click on <strong><em>Test Queries</em></strong> button (at the top) to validate that all four kpiNumber widgets are correct.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fa8a09&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fa8a09" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2368" height="1668" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.5.png" alt="Testing the first row widgets in Visual Designer" class="wp-image-45438" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.5.png 2368w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.5-300x211.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.5-1024x721.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.5-768x541.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.5-1536x1082.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.5-2048x1443.png 2048w" sizes="auto, (max-width: 2368px) 100vw, 2368px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-6-the-donut-contracts-by-agreement-type" class="wp-block-heading">6. The donut: contracts by agreement type</h2>



<p class="wp-block-paragraph">Click on the <strong><em>+ Add Widget</em></strong> button in the footer to add a new widget:</p>



<ul class="wp-block-list">
<li><strong>Widget Title</strong>: <strong><em>By Agreement Type</em></strong>.</li>



<li><strong>Widget Type</strong>: <strong><em>Donut Chart</em></strong>.</li>



<li><strong>Col Span</strong>: <strong><em>6</em></strong>.</li>



<li><strong>Row Span</strong>: <strong><em>2</em></strong> (chart widgets need height, see Post 3).</li>



<li><strong>Object Type(s)</strong>: <strong><em>Document</em></strong>.</li>



<li><strong>Class (optional)</strong>: <strong><em>Contract or Agreement</em></strong>.</li>



<li><strong>Aggregation Type</strong>: <strong><em>Group by Property</em></strong> (all objects with the same value of a specific property will be grouped together).</li>



<li><strong>Group-by Property</strong>: <strong><em>Agreement type (lookup)</em></strong> (the property to be used for the grouping).</li>



<li><strong>Drill-through Columns (comma-sep)</strong>: <strong><em>Agreement type, Effective through</em></strong>.</li>
</ul>



<h2 id="h-7-the-date-mode-gauge-countdown-to-next-expiry" class="wp-block-heading">7. The date-mode gauge: countdown to next expiry</h2>



<p class="wp-block-paragraph">The gauge is where things get more interesting. Here, I would like a dial showing how many days are left until the earliest/next contract expiry. This can be useful for making sure you never reach &#8220;0&#8221; (i.e. the date of today) on some tasks, like contracts renewal, period reviews of some documents, etc. You can see this as something similar to a fuel gauge in a car. If it reaches the minimum, you might be in trouble&#8230; The reducer is <strong><em>min</em></strong> on the <strong><em>Effective through</em></strong> property, and since this property is a date, it triggers date-mode automatically.</p>



<p class="wp-block-paragraph">Add the sixth widget. You know the drill, <strong><em>+ Add Widget</em></strong>:</p>



<ul class="wp-block-list">
<li><strong>Widget Title</strong>: <strong><em>Closest Expiry</em></strong>.</li>



<li><strong>Widget Type</strong>: <strong><em>Gauge</em></strong>.</li>



<li><strong>Col Span</strong>: <strong><em>6</em></strong>.</li>



<li><strong>Row Span</strong>: <strong><em>2</em></strong>.</li>



<li><strong>Object Type(s)</strong>: <strong><em>Document</em></strong>.</li>



<li><strong>Class (optional)</strong>: <strong><em>Contract or Agreement</em></strong>.</li>
</ul>



<p class="wp-block-paragraph">Let&#8217;s add a filter to keep only valid contracts again: click on the <strong><em>+ Add Filter</em></strong> button and a row appears:</p>



<ul class="wp-block-list">
<li><strong>Property</strong>: <strong><em>Effective through (date)</em></strong>.</li>



<li><strong>Operator</strong>: <strong><em>greater than or equal (&gt;=)</em></strong>.</li>



<li><strong>Value type</strong>: <strong><em>dateToken</em></strong>.</li>



<li><strong>Value</strong>: <strong><em>2011-11-01</em></strong> (instead of &#8220;@today&#8221; in a real vault).</li>
</ul>



<ul class="wp-block-list">
<li><strong>Reducer</strong>: <strong><em>min</em></strong>.</li>



<li><strong>Reducer Property</strong>: <strong><em>Effective through (date)</em></strong>.</li>



<li><strong>Drill-through Columns (comma-sep)</strong>: <strong><em>Agreement type, Effective through</em></strong>.</li>
</ul>



<p class="wp-block-paragraph">Now let&#8217;s add a first threshold: click on the <strong><em>+ Add Threshold</em></strong> button and a row appears:</p>



<ul class="wp-block-list">
<li><strong>Value</strong> (Threshold): <strong><em>0</em></strong> (so &#8220;today&#8221; = the contract expiry is very soon).</li>



<li><strong>Color</strong> (Threshold): <strong><em>red</em></strong> or <strong><em>#e74c3c</em></strong>.</li>
</ul>



<p class="wp-block-paragraph">Click on the <strong><em>+ Add Threshold</em></strong> button and a second row appears:</p>



<ul class="wp-block-list">
<li><strong>Value</strong> (Threshold): <strong><em>40</em></strong> (so &#8220;next month&#8221; = the contract expiry is coming).</li>



<li><strong>Color</strong> (Threshold): <strong><em>orange</em></strong> or <strong><em>#f39c12</em></strong>.</li>
</ul>



<p class="wp-block-paragraph">Click on the <strong><em>+ Add Threshold</em></strong> button and a third row appears:</p>



<ul class="wp-block-list">
<li><strong>Value</strong> (Threshold): <strong><em>80</em></strong> (so at least &#8220;2 months left&#8221; = the contract expiry is still far).</li>



<li><strong>Color</strong> (Threshold): <strong><em>green</em></strong> or <strong><em>#27ae60</em></strong>.</li>
</ul>



<ul class="wp-block-list">
<li><strong>Display Min (day offset)</strong>: <strong><em>0</em></strong> (so &#8220;today&#8221;).</li>



<li><strong>Display Max (day offset)</strong>: <strong><em>180</em></strong> (so &#8220;today&#8221; + 180 days).</li>



<li><strong>Display Unit</strong>: <strong><em>next expiry</em></strong>.</li>
</ul>



<h3 id="h-7-1-sample-vault-date-limitation" class="wp-block-heading">7.1. Sample Vault date limitation</h3>



<p class="wp-block-paragraph"><strong>Note:</strong> This widget will not fully work on the Sample Vault as-is, since the data is from 2011 and all contracts are already in the past. In a real vault, you would use <strong><em>@today</em></strong> as the filter value and set min/max to 0 and 180. The gauge would then show the number of days until the earliest active contract expires.</p>



<p class="wp-block-paragraph">On the Sample Vault, since 01-Nov-2011 is roughly 5350 days in the past, you would need to set min to &#8220;-5350&#8221; and max to &#8220;-5350+180&#8221; to see a meaningful result. The exact offset depends on when you read this, which is precisely why date tokens like <strong><em>@today</em></strong> exist &#8211; they adapt automatically.</p>



<p class="wp-block-paragraph">If I set the min/max offset to the accurate number of days since 01-Nov-2011, the gauge looks like this for end-users (that&#8217;s what It will look like on a real vault with <strong><em>@today</em></strong> and 0-180 values):</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fac4c1&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fac4c1" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="844" height="492" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.7.png" alt="Gauge in date-mode" class="wp-image-45439" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.7.png 844w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.7-300x175.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.7-768x448.png 768w" sizes="auto, (max-width: 844px) 100vw, 844px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-8-the-area-chart-expiry-per-year-and-per-agreement-type" class="wp-block-heading">8. The area chart: expiry per year and per agreement type</h2>



<p class="wp-block-paragraph">Add the seventh widget. It didn&#8217;t change since earlier, it&#8217;s still <strong><em>+ Add Widget</em></strong>&#8230;</p>



<ul class="wp-block-list">
<li><strong>Widget Title</strong>: <strong><em>Expiry per Year and Agreement Type</em></strong>.</li>



<li><strong>Widget Type</strong>: <strong><em>Area Chart</em></strong>.</li>



<li><strong>Col Span</strong>: <strong><em>12</em></strong>.</li>



<li><strong>Row Span</strong>: <strong><em>2</em></strong>.</li>



<li><strong>Object Type(s)</strong>: <strong><em>Document</em></strong>.</li>



<li><strong>Class (optional)</strong>: <strong><em>Contract or Agreement</em></strong>.</li>



<li><strong>Aggregation Type</strong>: <strong><em>Group by Date Bucket</em></strong> (all objects with the same date bucket for a specific property will be grouped together).</li>



<li><strong>Date Property</strong>: <strong><em>Effective through (date)</em></strong> (the property to be used for the grouping).</li>



<li><strong>Bucket Size</strong>: <strong><em>year</em></strong> (the objects within the same year will be in the same group).</li>



<li><strong>Series Property (optional)</strong>: <strong><em>Agreement type (lookup)</em></strong> (a second grouping level).</li>



<li><strong>Drill-through Columns (comma-sep)</strong>: <strong><em>Agreement type, Effective through</em></strong>.</li>



<li><strong>Smooth Lines</strong>: <strong><em>Yes</em></strong>.</li>
</ul>



<p class="wp-block-paragraph"><strong>Note:</strong> Instead of an <strong><em>Area Chart</em></strong>, you can use a <strong><em>Line Chart</em></strong> or <strong><em>Bar Chart</em></strong>, these three are usually interchangeable and can give the same amount of information visually.</p>



<h2 id="h-9-the-table-expired-contracts-to-review" class="wp-block-heading">9. The table: expired contracts to review</h2>



<p class="wp-block-paragraph">The last widget is a table showing the list of all expired contracts. This can be used for review or for some sales purpose, as previously mentioned. So let&#8217;s <strong><em>+ Add Widget</em></strong> one last time:</p>



<ul class="wp-block-list">
<li><strong>Widget Title</strong>: <strong><em>Expired Contracts to Review</em></strong>.</li>



<li><strong>Widget Type</strong>: <strong><em>Table</em></strong>.</li>



<li><strong>Col Span</strong>: <strong><em>12</em></strong>.</li>



<li><strong>Row Span</strong>: <strong><em>2</em></strong> (you can set 3 as well, for bigger table/lists).</li>



<li><strong>Object Type(s)</strong>: <strong><em>Document</em></strong>.</li>



<li><strong>Class (optional)</strong>: <strong><em>Contract or Agreement</em></strong>.</li>



<li><strong>Aggregation Type</strong>: <strong><em>List (list of individual objects)</em></strong>.</li>
</ul>



<p class="wp-block-paragraph">Click on the <strong><em>+ Add Filter</em></strong> button and a row appears:</p>



<ul class="wp-block-list">
<li><strong>Property</strong>: <strong><em>Effective through (date)</em></strong>.</li>



<li><strong>Operator</strong>: <strong><em>less than (&lt;)</em></strong>.</li>



<li><strong>Value type</strong>: <strong><em>dateToken</em></strong>.</li>



<li><strong>Value</strong>: <strong><em>2011-11-01</em></strong> (instead of &#8220;@today&#8221; in a real vault).</li>
</ul>



<ul class="wp-block-list">
<li><strong>Display Properties (comma-sep)</strong>: <strong><em>Agreement type, Effective through, Owner</em></strong>.</li>
</ul>



<h2 id="h-10-sanity-check-amp-saving" class="wp-block-heading">10. Sanity check &amp; Saving</h2>



<p class="wp-block-paragraph">Before saving, you can click on the <strong><em>Test Queries</em></strong> button from the toolbar to validate all widgets at once. The right-panel should list eight widgets, all green and without any warnings or errors. If something is wrong &#8211; a property name typo, an incompatible reducer / widget combination &#8211; this is where it would surface, with a clean message describing what to fix.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fae375&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fae375" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2370" height="1668" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10a.png" alt="Final result of the full dashboard and validation test successful" class="wp-image-45440" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10a.png 2370w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10a-300x211.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10a-1024x721.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10a-768x541.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10a-1536x1081.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10a-2048x1441.png 2048w" sizes="auto, (max-width: 2370px) 100vw, 2370px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">If it&#8217;s all green, then click on the <strong><em>Save</em></strong> button in the toolbar. The editor should display a message at the bottom saying it validated everything and then closes (you need to be quick to see the message). The Admin UI Dashboard tab refreshes, and the Contracts Snapshot dashboard now appears in the list, with its number of widgets and its description.</p>



<p class="wp-block-paragraph">Now, let&#8217;s see what it looks like from an end-user perspective after all that work! You can open the M-Files Web or Desktop (or do a refresh CTRL+F5 / CMD+R if it&#8217;s already loaded), open the right pane by clicking on the <strong>Dashboard</strong> tab, and pick <strong>Contracts Snapshot</strong> from the dropdown (it should be displayed automatically if it&#8217;s your first dashboard). Every chart element should be clickable (drill-through is enabled), and the PDF / CSV export buttons should also be present.</p>



<p class="wp-block-paragraph">See the first screenshot at the beginning of this blog post to see the final result that you can expect if you followed along the steps so far. Still, since you made it this far, here is what it looks like as a PDF Export:</p>



<div data-wp-interactive="core/file" class="wp-block-file"><object data-wp-bind--hidden="!state.hasPdfPreview" hidden class="wp-block-file__embed" data="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10b.pdf" type="application/pdf" style="width:100%;height:840px" aria-label="Embed of Contracts Snapshot (01-Nov-2011)."></object><a id="wp-block-file--media-76220328-afb2-4a60-86cd-f639a9c0350c" href="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10b.pdf">Contracts Snapshot (01-Nov-2011)</a><a href="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/8.10b.pdf" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-76220328-afb2-4a60-86cd-f639a9c0350c">Download</a></div>



<h2 id="h-11-closing-thoughts" class="wp-block-heading">11. Closing thoughts</h2>



<p class="wp-block-paragraph">I initially created the <strong>Business Dashboard</strong> with the JSON editor only, but I always had in mind that I needed to add a Visual Designer at some point, because not everybody knows how (or wants) to write JSON. Also, writing JSON directly requires you to know what is required, optional, supported or not supported. Even if the <strong><em>Test Queries</em></strong> and <strong><em>Save</em></strong> buttons both execute multiple layers of validations, to ensure everything you enter is supported, it still sends you warning after warning, error after error if you do not really know what you are doing. Therefore, the Visual Designer is great for that purpose, because you just click-through the details and you are guided all the way.</p>



<p class="wp-block-paragraph">The Visual / JSON toggle at the top of the editor lets you switch between authoring paths at any time, and your work is preserved in both directions. If you prefer hand-editing JSON or need to do bulk changes, the JSON mode is always available—but most administrators find the Visual Designer sufficient for their day-to-day work.</p>



<p class="wp-block-paragraph">Want to know more about this Business Dashboard? <a href="https://www.dbi-services.com/company/contact/" target="_blank" rel="noreferrer noopener">Contact us</a> and we will be happy to showcase it on <a href="https://www.m-files.com/" target="_blank" rel="noreferrer noopener">M-Files</a>.</p>



<p class="wp-block-paragraph">Quick access to previous blog posts of the series:</p>



<ul class="wp-block-list">
<li><strong><a href="https://www.dbi-services.com/blog/m-files-introducing-the-business-dashboard-module/" id="44913" target="_blank" rel="noreferrer noopener">Post 1</a></strong> &#8211; Introduction to the <strong>Business Dashboard</strong>.</li>



<li><strong><a href="https://www.dbi-services.com/blog/m-files-bd-end-user-experience/" id="44932" target="_blank" rel="noreferrer noopener">Post 2</a></strong> &#8211; The <strong>end-user experience</strong>: opening the panel, switching dashboards, drill-through, exports, favorites, sharing.</li>



<li><strong><a href="https://www.dbi-services.com/blog/m-files-bd-anatomy-of-a-dashboard-definition/" id="44952" target="_blank" rel="noreferrer noopener">Post 3</a></strong> &#8211; The anatomy of a <strong>dashboard definition</strong>: the JSON structure that drives everything.</li>



<li><strong>Posts <a href="https://www.dbi-services.com/blog/m-files-bd-scalar-widgets-kpinumber-and-gauge/" id="45018" target="_blank" rel="noreferrer noopener">4a</a>, <a href="https://www.dbi-services.com/blog/m-files-bd-trend-widgets-line-and-area/" id="45076" target="_blank" rel="noreferrer noopener">4b</a>, <a href="https://www.dbi-services.com/blog/m-files-bd-distribution-and-tabular-widgets-donut-bar-table/" id="45109" target="_blank" rel="noreferrer noopener">4c</a></strong> &#8211; The <strong>widget catalog</strong>, split by type family: scalar widgets (<strong><em>kpiNumber</em></strong>, <strong><em>gauge</em></strong>), trend widgets (<strong><em>line</em></strong>, <strong><em>area</em></strong>), and distribution / tabular widgets (<strong><em>donut</em></strong>, <strong><em>bar</em></strong>, <strong><em>table</em></strong>).</li>



<li><strong><a href="https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/" id="45175" target="_blank" rel="noreferrer noopener">Post 5</a></strong> &#8211; Writing queries: <strong><em>objectType</em></strong>, <strong><em>class</em></strong>, <strong>filters</strong>, date tokens.</li>



<li><strong><a href="https://www.dbi-services.com/blog/m-files-bd-aggregations-reducers-and-series/" id="45206" target="_blank" rel="noreferrer noopener">Post 6</a></strong> &#8211; <strong>Aggregations</strong> and <strong>reducers</strong>.</li>



<li><strong><a href="https://www.dbi-services.com/blog/m-files-bd-the-admin-part/" id="45312" target="_blank" rel="noreferrer noopener">Post 7</a></strong> &#8211; The <strong>Admin tab</strong>: actions, Visual Designer / JSON editor, validation, import / export, access control.</li>
</ul>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-bd-putting-it-together-with-the-visual-designer/">M-Files BD &#8211; Putting it together with the Visual Designer</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/m-files-bd-putting-it-together-with-the-visual-designer/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>M-Files BD &#8211; The Admin part</title>
		<link>https://www.dbi-services.com/blog/m-files-bd-the-admin-part/</link>
					<comments>https://www.dbi-services.com/blog/m-files-bd-the-admin-part/#respond</comments>
		
		<dc:creator><![CDATA[Morgan Patou]]></dc:creator>
		<pubDate>Thu, 25 Jun 2026 23:29:53 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[Admin]]></category>
		<category><![CDATA[Business Dashboard]]></category>
		<category><![CDATA[JSON Editor]]></category>
		<category><![CDATA[M-Files]]></category>
		<category><![CDATA[Visual Designer]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45312</guid>

					<description><![CDATA[<p>So far in this series I have covered what an end user sees, the anatomy of a dashboard definition, the seven widget types (scalar, trend, and the rest), the query side, including the aggregations. Time to look at the surface where the administrator actually spends time: the Dashboard tab in M-Files Admin. This is also [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-bd-the-admin-part/">M-Files BD &#8211; The Admin part</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">So far in this series I have covered what an <a href="https://www.dbi-services.com/blog/m-files-bd-end-user-experience/" id="44932" target="_blank" rel="noreferrer noopener">end user sees</a>, the <a href="https://www.dbi-services.com/blog/m-files-bd-anatomy-of-a-dashboard-definition/" id="44952" target="_blank" rel="noreferrer noopener">anatomy of a dashboard definition</a>, the seven widget types (<a href="https://www.dbi-services.com/blog/m-files-bd-scalar-widgets-kpinumber-and-gauge/" id="45018" target="_blank" rel="noreferrer noopener">scalar</a>, <a href="https://www.dbi-services.com/blog/m-files-bd-trend-widgets-line-and-area/" id="45076" target="_blank" rel="noreferrer noopener">trend</a>, and <a href="https://www.dbi-services.com/blog/m-files-bd-distribution-and-tabular-widgets-donut-bar-table/" id="45109" target="_blank" rel="noreferrer noopener">the rest</a>), the <a href="https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/" id="45175" target="_blank" rel="noreferrer noopener">query side</a>, including the <a href="https://www.dbi-services.com/blog/m-files-bd-aggregations-reducers-and-series/" id="45206" target="_blank" rel="noreferrer noopener">aggregations</a>. Time to look at the surface where the administrator actually spends time: the <strong>Dashboard tab in M-Files Admin</strong>.</p>



<p class="wp-block-paragraph">This is also where the Visual Designer lives. Some administrators write JSON directly, others stay in the visual canvas, others switch back and forth. All three workflows are supported, and the two modes are kept in sync at every moment.</p>



<h2 id="h-1-where-to-find-the-admin-tab" class="wp-block-heading">1. Where to find the Admin tab</h2>



<p class="wp-block-paragraph">Once it has been installed (e.g. via <strong>Vault</strong> -&gt; Right click -&gt; <strong>Applications</strong> -&gt; <strong>Install&#8230;</strong>), the Business Dashboard will be present in the M-Files Admin configuration page:</p>



<ol class="wp-block-list">
<li>Open <strong>M-Files Admin</strong> (the desktop management application).</li>



<li>Connect to your server and open the target vault.</li>



<li>In the left tree, navigate to <strong>Configurations</strong> -&gt; <strong>Other Applications</strong>.</li>



<li>Find <strong>dbi services Business Dashboard</strong> and click it.</li>



<li>You should end up on the <strong>Dashboard</strong> tab.</li>
</ol>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fc0eb6&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fc0eb6" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2560" height="1418" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1-scaled.png" alt="Business Dashboard Admin part" class="wp-image-45313" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1-scaled.png 2560w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1-300x166.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1-1024x567.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1-768x425.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1-1536x851.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1-2048x1134.png 2048w" sizes="auto, (max-width: 2560px) 100vw, 2560px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">The first thing you will probably want to do is to look at the <strong>Configuration</strong> tab, that sits right next to the <strong>Dashboard</strong> one. This is where you can configure the <strong>Business Dashboard</strong> as needed.</p>



<h3 id="h-1-1-the-configuration-tab-general-settings" class="wp-block-heading">1.1. The Configuration tab &#8211; &#8220;General&#8221; settings</h3>



<p class="wp-block-paragraph">At the time of writing this blog, the <strong>General</strong> section of the configuration is rather short. It only contains 4 settings:</p>



<ul class="wp-block-list">
<li><strong><em>Table page size</em></strong>: controls the pagination of all tables (list &amp; drill-through modals), i.e. the maximum number of rows that can be displayed before a new page is required. (default: 15).</li>



<li><strong><em>Default widget color</em></strong>: controls the base color of the widgets (end-user side), like the number inside the kpiNumber, the gauge and its pointer, the table header, the line and area. It&#8217;s only the base color, so it still gets updated/overwritten by the display.thresholds parameter of each widget. (default: #006eef &#8211; the M-Files &#8220;standard&#8221; blue).</li>



<li><strong><em>Default chrome color</em></strong>: controls the base color for the &#8220;chrome&#8221; things (end-user side), for example the links shown inside the tables, to navigate to objects, as well as the spinner when dashboards/widgets are loading. (default: #006eef).</li>



<li><strong><em>Admin UI accent color</em></strong>: controls the base color for the buttons (admin side), like Save, Test Queries, etc. (default: #006eef).</li>
</ul>



<p class="wp-block-paragraph">Exactly like any other M-Files configuration items, as soon as you modify one of these values, the &#8220;Save&#8221; and &#8220;Discard&#8221; buttons appear so you can either persist and remove what you just changed.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fc2fc6&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fc2fc6" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="1756" height="704" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.1.png" alt="Business Dashboard Admin part - General settings" class="wp-image-45314" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.1.png 1756w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.1-300x120.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.1-1024x411.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.1-768x308.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.1-1536x616.png 1536w" sizes="auto, (max-width: 1756px) 100vw, 1756px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h3 id="h-1-2-the-configuration-tab-new-dashboard-defaults-settings" class="wp-block-heading">1.2. The Configuration tab &#8211; &#8220;New Dashboard Defaults&#8221; settings</h3>



<p class="wp-block-paragraph">The second section inside the configuration tab allows to overwrite the default settings for <strong><em>new</em></strong> dashboards. As I mentioned in previous blogs, a dashboard has around 10 configurable parameters, that controls things like which features are allowed, whether users can refresh or if it should be automatic, etc. All these parameters have a default value, which is usually &#8220;No&#8221; (disabled / do not bypass important checks).</p>



<p class="wp-block-paragraph">This section will make it so that all dashboards created in the future will use your own personalized default values, so you don&#8217;t have to configure the same things over and over again. It doesn&#8217;t have any impact on already configured dashboards AND it doesn&#8217;t force anything. It is simply a replacement of default values, which means that you can still overwrite these settings inside each dashboards as required (because specific dashboards might have different needs).</p>



<ul class="wp-block-list">
<li><strong><em>Auto-refresh enabled</em></strong>: controls whether the automatic refresh is enabled. (default: No).</li>



<li><strong><em>Auto-refresh interval (seconds)</em></strong>: controls the interval between two automatic refresh. (default: 300).</li>



<li><strong><em>User can toggle auto-refresh</em></strong>: controls whether users can enable the automatic refresh. (default: No).</li>



<li><strong><em>Export to PDF enabled</em></strong>: controls whether the PDF export is enabled. (default: No).</li>



<li><strong><em>Export to CSV enabled</em></strong>: controls whether the CSV export is enabled. (default: No).</li>



<li><strong><em>Drill-through enabled</em></strong>: controls whether the drill-through is enabled, which also controls the navigation to target objects. (default: No).</li>



<li><strong><em>Drill-through max results</em></strong>: controls how many results will be paginated on drill-through modals. (default: 300).</li>



<li><strong><em>Server scan max results</em></strong>: controls how many results we can return when looking for objects. (default: 500).</li>



<li><strong><em>Skip template check</em></strong>: controls whether the &#8220;template check&#8221; are skipped. More on that later in this post. (default: No).</li>



<li><strong><em>Skip object permission check</em></strong>: controls whether the user&#8217;s ACLs are respected. More on that later in this post. (default: No).</li>
</ul>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fc50de&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fc50de" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="1756" height="970" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.2.png" alt="Business Dashboard Admin part - Default settings" class="wp-image-45315" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.2.png 1756w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.2-300x166.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.2-1024x566.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.2-768x424.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.2-1536x848.png 1536w" sizes="auto, (max-width: 1756px) 100vw, 1756px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h3 id="h-1-3-the-configuration-tab-logging-settings" class="wp-block-heading">1.3. The Configuration tab &#8211; &#8220;Logging&#8221; settings</h3>



<p class="wp-block-paragraph">The third section contains all the standard M-Files logging configurations. In there, you can enable the global logging, then create some specific targets, like a file target (writing to a log file on the local file system), event log target (writing to the Windows Event Log), database target (writing to a specific DB), etc&#8230;</p>



<p class="wp-block-paragraph">These are usual M-Files configurations, so I won&#8217;t describe them all, but in short, you only have to enable the global logging, defining a target with the appropriate log level and target-specific details as you see fit.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fc588c&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fc588c" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="1754" height="1038" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.3.png" alt="Business Dashboard Admin part - Logging settings" class="wp-image-45316" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.3.png 1754w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.3-300x178.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.3-1024x606.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.3-768x454.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.1.3-1536x909.png 1536w" sizes="auto, (max-width: 1754px) 100vw, 1754px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-2-the-dashboard-list-and-action-buttons" class="wp-block-heading">2. The dashboard list and action buttons</h2>



<p class="wp-block-paragraph">The Dashboard tab shows all currently configured dashboards (or nothing if you have none yet) in an alternating-row list. Each row contains additional details such as the count of widget inside this dashboard, the access details (whether it can be accessed by everybody or if it&#8217;s restricted to some people/groups only) and the description.</p>



<p class="wp-block-paragraph">Each dashboard row also has a compact <strong>icon button bar</strong> for quick access: <code>↑ ↓ 🖉 ⧉ ⎙ 🗑</code> (move up / move down / edit / clone / export / delete) (It took me so long to find these icons!). These per-row buttons provide faster access to the most common operations without opening a selector modal from the top-bar buttons.</p>



<p class="wp-block-paragraph">Speaking of top-bar buttons, you saw them already, but at the very top, you can see global action buttons available from any of the tabs:</p>



<figure class="wp-block-table"><table><thead><tr><th>Button</th><th>Action</th></tr></thead><tbody><tr><td><strong>Add New</strong></td><td>Opens the editor pre-filled with a blank dashboard template (Visual Designer mode by default)</td></tr><tr><td><strong>Import</strong></td><td>Imports one or more dashboards from a <strong><em>.json</em></strong> file (merges with existing)</td></tr><tr><td><strong>Reorder&#8230;</strong></td><td>Opens a modal page, with the list of all dashboards to re-order them</td></tr><tr><td><strong>Edit&#8230;</strong></td><td>Opens a selector to choose and edit an existing dashboard</td></tr><tr><td><strong>Clone&#8230;</strong></td><td>Duplicates an existing dashboard with a new UUID and a <strong><em>&#8221; (copy)&#8221;</em></strong> name suffix</td></tr><tr><td><strong>Export&#8230;</strong></td><td>Opens a selector to choose and export one or all dashboards, to a <strong><em>.json</em></strong> file</td></tr><tr><td><strong>Delete&#8230;</strong></td><td>Opens a selector to choose and delete one or all dashboards, with a confirmation message</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">More on these actions lower in this blog post.</p>



<h2 id="h-3-the-editor-two-modes-one-source-of-truth" class="wp-block-heading">3. The editor: two modes, one source of truth</h2>



<p class="wp-block-paragraph">When you click <strong><em>Add New</em></strong> or <strong><em>Edit&#8230;</em></strong>, the editor modal opens. At the top of the toolbar, two buttons toggle between the modes:</p>



<ul class="wp-block-list">
<li><strong>[Visual]</strong> <em>(default)</em>: the &#8220;Visual Designer&#8221;, a form-based designer with a canvas of widget tiles and a side configuration panel.</li>



<li><strong>[JSON]</strong>: the &#8220;JSON Editor&#8221;, a manual code box that allows you to write JSON.</li>
</ul>



<p class="wp-block-paragraph">The two modes are <strong>kept in sync at all times</strong>. Switching from Visual to JSON shows the current visual state serialized, switching back re-parses the JSON so that the Visual Designer is also up-to-date.</p>



<p class="wp-block-paragraph">The editor is split into four regions:</p>



<ul class="wp-block-list">
<li><strong>The top bar</strong> shows main buttons to switch between modes, load an example dashboard (to give you some ideas), format JSON (when in JSON Editor mode), test all widgets at once or save.</li>



<li><strong>The</strong> <strong>left panel</strong> shows either the widgets display in Visual Designer mode or the JSON code block in JSON Editor mode.</li>



<li><strong>The footer bar</strong> (anchored below the canvas) has four buttons, to show the dashboard settings, add a new widget, clone an existing widget or test a widget. There is also a small place below these buttons kept for status messages, to let you know when something was done or if there are errors, etc.</li>



<li><strong>The config panel (right panel)</strong> shows the editable fields. In Visual Designer mode, it shows dashboards and widget configurations. In JSON Editor mode, it shows the user and group pickers only. Both modes also includes the &#8220;Test Results&#8221; which contains execution/validation details.</li>
</ul>



<h3 id="h-3-1-visual-mode" class="wp-block-heading">3.1. Visual mode</h3>



<p class="wp-block-paragraph">As said, the left panel contains the widget display, with their title, type, aggregation, objectType. It also display quick action buttons such as up-down or delete, so you can quickly re-arrange the widgets and get the visual look&amp;feel that you want. The right panel contains the dashboard settings by default (which we described above already). When a widget is selected, the right panel will then display these different building blocks:</p>



<figure class="wp-block-table"><table><thead><tr><th>Section</th><th>Fields</th></tr></thead><tbody><tr><td><strong>Basics</strong></td><td>Widget title, description, translations, type and size (Col Span (1-12), Row Span (1-12))</td></tr><tr><td><strong>Data Source</strong></td><td>Object Type(s), Class and aggregation type</td></tr><tr><td><strong>Filters</strong></td><td>Add / remove filter rows, with their associated properties, operators, value type and value</td></tr><tr><td><strong>Aggregation</strong></td><td>The details of the aggregation, like grouping property, bucket size, reducer, reducer property, series property</td></tr><tr><td><strong>Display</strong></td><td>Any possible display options such as thresholds (coloring), unit, min / max, decimals (0-9), smooth or bar layout</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">With this Visual Designer, you are guided by selecting things one by one. You don&#8217;t see ALL options right from the beginning, depending on what you select, only what is possible will be offered, so you can focus on what makes sense for you.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fc62aa&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fc62aa" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2412" height="1670" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.1.png" alt="Business Dashboard Visual Designer" class="wp-image-45317" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.1.png 2412w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.1-300x208.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.1-1024x709.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.1-768x532.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.1-1536x1063.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.1-2048x1418.png 2048w" sizes="auto, (max-width: 2412px) 100vw, 2412px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h3 id="h-3-2-json-mode" class="wp-block-heading">3.2. JSON mode</h3>



<p class="wp-block-paragraph">The JSON Editor is simply a code box which allows you to enter JSON. It shares the top-bar buttons with the Visual Designer, the only difference being the &#8220;Format JSON&#8221; one that is enabled only when in JSON mode.</p>



<p class="wp-block-paragraph">I might extend this feature later, but for now there is no completion feature, it simply has a bit of highlighting so you can spot errors easily and allows for code drag-and-drop.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fc8045&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fc8045" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2410" height="1670" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.2.png" alt="Business Dashboard JSON Editor" class="wp-image-45318" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.2.png 2410w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.2-300x208.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.2-1024x710.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.2-768x532.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.2-1536x1064.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.3.2-2048x1419.png 2048w" sizes="auto, (max-width: 2410px) 100vw, 2410px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-4-validation" class="wp-block-heading">4. Validation</h2>



<h3 id="h-4-1-the-two-stage-validators" class="wp-block-heading">4.1. The two-stage validators</h3>



<p class="wp-block-paragraph">Whether you click on <strong><em>Test Queries</em></strong> (all widgets), <strong><em>Test Widget</em></strong> (1 widget) or <strong><em>Save</em></strong> and whether you are doing it from Visual or JSON mode, the engine will run a 2-stage validation of what you currently configured.</p>



<h4 id="h-4-1-1-stage-1" class="wp-block-heading">4.1.1. Stage 1</h4>



<p class="wp-block-paragraph">The first stage is simply a structural one. For example, are all mandatory fields present, are known values (e.g. widget types) within the accepted ones, etc. This is very fast and it doesn&#8217;t require a connection to the vault, so that we can already surface global issues.</p>



<p class="wp-block-paragraph"><strong>Note:</strong> Only the &#8220;Import&#8221; feature bypasses the stage-2 validation and only performs a structural check. When using the import feature, we kinda expect that the JSON was exported from another vault and therefore if it existed inside a previous environment, it means that it is a valid dashboard. Doing the stage-2 validation on each import would considerably slow it down (especially if you import 10, 50 or even 100 dashboards at once).</p>



<h4 id="h-4-1-2-stage-2" class="wp-block-heading">4.1.2. Stage 2</h4>



<p class="wp-block-paragraph">The second stage is much more complex and it will verify if you made any mistakes by really checking what&#8217;s available inside the vault. This will mark typos such as wrong object types, classes or properties. It will also try to resolve value lists items that you references, to make sure they are indeed present. This is obviously slightly slower, but still completes within a couple seconds for most dashboards. It also gives you a good idea of how fast this dashboard will load for end-users, since it&#8217;s actually executing all queries.</p>



<p class="wp-block-paragraph"><strong>Note:</strong> For Test Widget, the engine will only test one specific widget, as said earlier. Therefore, it automatically adds a valid dashboard structure around it so it can pass the stage-1 validation for the dashboard level. Only stage-1 validation of the widget level is tested and the query execution for the phase-2, obviously.</p>



<h3 id="h-4-2-errors-and-warnings" class="wp-block-heading">4.2. Errors and warnings</h3>



<p class="wp-block-paragraph">The Test Results panel shows three possible statuses per widget:</p>



<ul class="wp-block-list">
<li><strong>OK</strong>: the query succeeded and the result is renderable.</li>



<li><strong>Warning</strong> (amber): the query succeeded but the result will probably not be rendered the way you would like to. A common occurrence is a date-valued reducer on a chart widget, where the message will tell you to switch to <strong><em>kpiNumber</em></strong>, <strong><em>table</em></strong>, or <strong><em>gauge</em></strong>.</li>



<li><strong>Error</strong> (red): the query failed. The message tells you which property name or class name to check or change.</li>
</ul>



<p class="wp-block-paragraph">Note: A warning will still allow the Save to complete, because even if it might not render, a placeholder widget will replace the expected chart. On the other hand, an error will prevent the Save operation because we shouldn&#8217;t persist something that is structurally or fundamentally wrong. Here is an example from the Example Dashboard where I specifically introduced some mistakes:</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fc88fc&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fc88fc" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="2412" height="1670" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.4.2.png" alt="Business Dashboard JSON Editor with errors, warnings and OK messages" class="wp-image-45319" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.4.2.png 2412w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.4.2-300x208.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.4.2-1024x709.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.4.2-768x532.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.4.2-1536x1063.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.4.2-2048x1418.png 2048w" sizes="auto, (max-width: 2412px) 100vw, 2412px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-5-import-and-export" class="wp-block-heading">5. Import and Export</h2>



<p class="wp-block-paragraph">Dashboards live in the vault&#8217;s Named Value Storage (NVS). To facilitate transfer from DEV to QA/INT to PROD or any other environments you might have, an import/export feature was added on the M-Files Admin. To use it, simply click on the <strong><em>Import</em></strong> or <strong><em>Export&#8230;</em></strong> buttons.</p>



<p class="wp-block-paragraph">First, the <strong><em>Export&#8230;</em></strong> one, open a prompt so you can select which dashboard you would like to export. On that prompt, there is also a button to <strong><em>Export All</em></strong>. If you select a single dashboard to be exported, the JSON file generated will have, by default, the name of the dashboard (you can set the name that you want, of course). If you chose to export all, then the name will simply be &#8220;dashboards-export.json&#8221; and inside, you will find an array of dashboard definition.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fc9d27&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fc9d27" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="1257" height="869" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.1.png" alt="Business Dashboard Export Dashboard" class="wp-image-45320" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.1.png 1257w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.1-300x207.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.1-1024x708.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.1-768x531.png 768w" sizes="auto, (max-width: 1257px) 100vw, 1257px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<p class="wp-block-paragraph">Once it has been exported, you can then <strong><em>Import</em></strong> it somewhere else (or on the same vault, it will merge it with existing dashboards &#8211; that&#8217;s why IDs are important!). Another prompt opens and you can then select a file (through Windows Explorer) or you can also drag-and-drop JSON to it. Its content is then displayed inside the prompt so you can take a look. Once you hit the import button at the bottom, it will quickly validate the dashboard definition and if everything is good, it will be imported into the vault.</p>



<figure data-wp-context="{&quot;imageId&quot;:&quot;6a66004fca2c5&quot;}" data-wp-interactive="core/image" data-wp-key="6a66004fca2c5" class="wp-block-image size-full wp-lightbox-container"><img loading="lazy" decoding="async" width="1263" height="929" data-wp-class--hide="state.isContentHidden" data-wp-class--show="state.isContentVisible" data-wp-init="callbacks.setButtonStyles" data-wp-on--click="actions.showLightbox" data-wp-on--load="callbacks.setButtonStyles" data-wp-on--pointerdown="actions.preloadImage" data-wp-on--pointerenter="actions.preloadImageWithDelay" data-wp-on--pointerleave="actions.cancelPreload" data-wp-on-window--resize="callbacks.setButtonStyles" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.2.png" alt="Business Dashboard Import Dashboard" class="wp-image-45321" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.2.png 1263w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.2-300x221.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.2-1024x753.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/7.5.2-768x565.png 768w" sizes="auto, (max-width: 1263px) 100vw, 1263px" /><button
			class="lightbox-trigger"
			type="button"
			aria-haspopup="dialog"
			data-wp-bind--aria-label="state.thisImage.triggerButtonAriaLabel"
			data-wp-init="callbacks.initTriggerButton"
			data-wp-on--click="actions.showLightbox"
			data-wp-style--right="state.thisImage.buttonRight"
			data-wp-style--top="state.thisImage.buttonTop"
		>
			<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" viewBox="0 0 12 12">
				<path fill="#fff" d="M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z" />
			</svg>
		</button></figure>



<h2 id="h-6-the-reorder-and-clone-modals" class="wp-block-heading">6. The Reorder and Clone modals</h2>



<p class="wp-block-paragraph">Two smaller actions but these are still worth mentioning because they fix small but real pain points. The <strong><em>Reorder&#8230;</em></strong> one allows you to use the up-down arrows &#8211; same as from the dashboard list shown in the default Dashboard tab. But you have access to another facilitator with the global button: dashboards are numbered with a small text box that you can update. For example, if you have 5 dashboards, the last one will have a small text box with a &#8220;5&#8221; inside. If you update that value to &#8220;1&#8221;, then this dashboard will automatically become the 1st one. This allows for faster re-ordering than clicking 4 times on the arrow-up icon, especially when you have 50+ dashboards to manage.</p>



<p class="wp-block-paragraph">If you have a good idea of what you want to build and you know that one of your dashboards is already pretty similar, then instead of recreating everything from scratch, you can use the <strong><em>Clone&#8230;</em></strong> feature. It allows the duplication of an existing dashboard into a new one. The new one will use new IDs for both the dashboard and all the widgets, and to be able to differentiate them, the name will have a <strong><em>&#8221; (copy)&#8221;</em></strong> suffix. I see you coming &#8211; if you duplicate the same dashboard multiple times, it will be <strong><em>&#8221; (copy 2)&#8221;</em></strong>, then <strong><em>&#8221; (copy 3)&#8221;</em></strong>, etc.</p>



<h2 id="h-7-access-control-two-level-model" class="wp-block-heading">7. Access control &#8211; two-level model</h2>



<p class="wp-block-paragraph">Access control in the Business Dashboard works on two distinct levels:</p>



<figure class="wp-block-table"><table><thead><tr><th>Level</th><th>Field</th><th>Default</th><th>What it controls</th></tr></thead><tbody><tr><td>Dashboard visibility</td><td><strong><em>assignedTo</em></strong></td><td>Public</td><td>Who can see and open the dashboard</td></tr><tr><td>Per-object data filtering</td><td><strong><em>skipObjectPermissionCheck</em></strong></td><td><strong><em>&#8220;No&#8221;</em></strong> (= check = ACLs are respected)</td><td>Whether widget data respects each user&#8217;s individual M-Files object ACLs / permissions</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">The two are independent. <strong><em>assignedTo</em></strong> says &#8220;you are allowed to open this dashboard&#8221;. <strong><em>skipObjectPermissionCheck</em></strong> says &#8220;once you are inside, do widgets show you everything or only what your own permissions allows you to see and read&#8221;.</p>



<h3 id="h-7-1-assignedto-who-can-open-the-dashboard" class="wp-block-heading">7.1. assignedTo &#8211; who can open the dashboard</h3>



<p class="wp-block-paragraph">By default (no <strong><em>assignedTo</em></strong> field or an empty array), a dashboard is visible to <strong>everyone</strong> who has access to the vault. To restrict the access, you can define either a list of users or groups:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
&quot;assignedTo&quot;: {
  &quot;users&quot;: &#x5B;&quot;Morgan.Patou&quot;],
  &quot;groups&quot;: &#x5B;&quot;Finance Team&quot;, &quot;Management&quot;]
}
</pre></div>


<p class="wp-block-paragraph">Access is granted to <strong>any user who matches any entry</strong> (OR semantics), i.e. part of the users list or part of any of the group from the groups list.</p>



<h3 id="h-7-2-skipobjectpermissioncheck-what-data-shows-up" class="wp-block-heading">7.2. skipObjectPermissionCheck &#8211; what data shows up</h3>



<p class="wp-block-paragraph">By default (<strong><em>&#8220;No&#8221;</em></strong>), M-Files permissions will be respected, so you cannot see things that you aren&#8217;t entitled to see. However, there are valid use cases where you would need to specifically bypass object-level permissions.</p>



<p class="wp-block-paragraph">For example, you probably don&#8217;t want all your employees to see all the HR documents, all the contracts, etc. However, there are often KPIs that could be rendered &#8220;Public&#8221;, or at least given to a broader audience than the people that originally have access to these objects. Maybe you would like to share some executive or management reporting KPIs, some Sales Performance details, or some Security Information.</p>



<p class="wp-block-paragraph">That is entirely up to you and, in addition, you control whether end-users can use the drill-through or not and what metadata the drill-through should show (if anything at all). Again, it&#8217;s not because you show KPIs that users will be able to find and read classified documents. M-Files permissions on the objects themselves (preview its content, listing all metadata, downloading the file, etc.) will always be respected. What the Business Dashboard allows is fully configurable, so there are no real security concerns.</p>



<p class="wp-block-paragraph"><strong>When to use each:</strong></p>



<ul class="wp-block-list">
<li><strong>&#8220;No&#8221;</strong> (default): when different users should see different numbers based on their own M-Files ACL.</li>



<li><strong>&#8220;Yes&#8221;</strong>: when every authorized viewer should see identical numbers and performance matters (typical for overview dashboards that don&#8217;t go into details). Combine with <strong><em>assignedTo</em></strong> to restrict who can open it.</li>
</ul>



<h2 id="h-8-performance" class="wp-block-heading">8. Performance</h2>



<p class="wp-block-paragraph">I already mentioned them in earlier posts, but I think it still makes sense to summarize it all again here, since we are talking about the Admin side of the <strong>Business Dashboard</strong>. There are multiple parameters that have performance impacts. Some of them are very low, some aren&#8217;t.</p>



<h3 id="h-8-1-performance-gains" class="wp-block-heading">8.1 Performance gains</h3>



<p class="wp-block-paragraph">These are the things that will have either no negative performance impact or even show performance gains:</p>



<ul class="wp-block-list">
<li><strong><em>exportToPdfEnabled</em></strong> / <strong><em>exportToCsvEnabled</em></strong>: these two parameters are similar in the sense that they only enable one specific feature and it has no performance impact, since it runs fully on client side. All the data is already available in the client&#8217;s dashboard, so it has no impact on the server.</li>



<li><strong><em>skipObjectPermissionCheck</em></strong>: by default, it will execute ACLs checks to ensure users only see objects they are entitled to. The way I implemented that means that whether you are doing server-level queries or user-level queries has absolutely no impact on the performance. In fact, it might be even faster to execute the ACLs checks, since you might return less objects that what the server would have access to. Therefore, the performance impact is null or slightly positive.</li>



<li><strong><em>objectType</em></strong> / <strong><em>class</em></strong> / <strong><em>count reducer</em></strong> / <strong><em>native filters</em></strong>: adding a restriction on class and adding native filters will mean less results to be fetched and processed. As previously said (c.f. <a href="https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/" target="_blank" rel="noreferrer noopener">Post 5</a>), for optimal performance, make sure to restrict the objectTypes / class and apply native filters as much as possible. Therefore, adding these will definitively bring performance gains.</li>
</ul>



<h3 id="h-8-2-potential-for-medium-high-performance-impact" class="wp-block-heading">8.2. Potential for Medium / High performance impact</h3>



<p class="wp-block-paragraph">Depending on how you use them, these settings can have very low or very high impact on the performance of the <strong>Business Dashboard</strong>:</p>



<ul class="wp-block-list">
<li><strong><em>autoRefreshEnabled</em></strong> / <strong><em>autoRefreshIntervalSeconds</em></strong> / <strong><em>userCanToggleAutoRefresh</em></strong>: control the refresh of widgets/dashboards. The impact depends on multiple factors, like how many users, widgets, objects fetched, etc&#8230; These will increase the &#8220;regular&#8221; load on the server, not really impact the loading speed&#8230; The performance impact can go from very low (e.g. refresh every 5 minutes with low-demanding widgets) to pretty high (e.g. refresh every 15 seconds with 10&#8217;000+ objects widgets)&#8230;</li>



<li><strong><em>serverScanMaxResults</em></strong> / <strong><em>drillThroughEnabled</em></strong> / <strong><em>drillThroughMaxResults</em></strong>: define the maximum results for the widget or the drill-through. When hit, a <strong><em>Partial results</em></strong> badge appears, to show results may be incomplete. These are basically <strong>fail-safe/lifeline</strong>, to make sure widgets do not try to retrieve the whole vault&#8217;s content. The performance impact will be important if you disable this (&#8220;0&#8221; = unlimited results) and if you try to fetch 100&#8217;000 objects.</li>



<li><strong><em>skipTemplateCheck</em></strong> / <strong><em>non-count reducers</em></strong> / <strong><em>post-filters</em></strong>: all these parameters means that there is a need to fetch additional metadata from the vault, for all objects. If you want to execute the template check, apply a non-count reducer on a property or a post-filter, you will first fetch all objects, and then, for each of them, fetch their associated metadata. As far as I culd see, M-Files doesn&#8217;t allow to return both objects and their metadata at the same time. The performance impact will be grow with the number of objects you fetch and need to process.</li>
</ul>



<p class="wp-block-paragraph"><strong>Note:</strong> The performance isn&#8217;t bad. There are a few tricks I implemented to make sure the performance stays pretty good, so you can load a dashboard fetching 5&#8217;000+ objects in less than 1.5 seconds, with the right configuration.</p>



<h2 id="h-11-wrap-up" class="wp-block-heading">11. Wrap-up</h2>



<p class="wp-block-paragraph">The Admin tab is the place administrators will spend the majority of their time. The Visual Designer is there to lower the complexity of creating and managing dashboards. Even a JSON-averse administrator can build a full dashboard without ever opening the JSON editor. However, it is still available for power users that feel comfortable with it, as it gives them the flexibility, quick copy/paste, and bulk-edit comfort they can expect.</p>



<p class="wp-block-paragraph">The next, and probably last, <strong><a href="https://www.dbi-services.com/blog/m-files-bd-putting-it-together-with-the-visual-designer/" id="45433" target="_blank" rel="noreferrer noopener">Post 8</a></strong> will walk you through building a complete Contracts dashboard on the M-Files Sample Vault. I will use the Visual Designer only, so you can follow along and adapt it to your own vault.</p>



<p class="wp-block-paragraph">Want to know more about this Business Dashboard? <a href="https://www.dbi-services.com/company/contact/" target="_blank" rel="noreferrer noopener">Contact us</a> and we will be happy to showcase it on <a href="https://www.m-files.com/" target="_blank" rel="noreferrer noopener">M-Files</a>.</p>



<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-bd-the-admin-part/">M-Files BD &#8211; The Admin part</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/m-files-bd-the-admin-part/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>After years of ECM projects, here’s how I do things differently nowadays</title>
		<link>https://www.dbi-services.com/blog/after-years-of-ecm-projects-heres-how-i-do-things-differently-nowadays/</link>
					<comments>https://www.dbi-services.com/blog/after-years-of-ecm-projects-heres-how-i-do-things-differently-nowadays/#respond</comments>
		
		<dc:creator><![CDATA[Guillaume Meunier]]></dc:creator>
		<pubDate>Thu, 25 Jun 2026 15:59:38 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[digitalization]]></category>
		<category><![CDATA[Enterprise Content Management]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45188</guid>

					<description><![CDATA[<p>In IT, it is essential to stay up to date, as technology evolves at an ever-accelerating pace. As consultants, we constantly face new challenges, many of which extend beyond purely technical matters, while adapting to diverse contexts and audiences. That’s what makes this profession so exciting! At dbi services, knowledge sharing is deeply embedded in [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/after-years-of-ecm-projects-heres-how-i-do-things-differently-nowadays/">After years of ECM projects, here’s how I do things differently nowadays</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In IT, it is essential to stay up to date, as technology evolves at an ever-accelerating pace. </p>



<p class="wp-block-paragraph">As consultants, we constantly face new challenges, many of which extend beyond purely technical matters, while adapting to diverse contexts and audiences.</p>



<p class="wp-block-paragraph">That’s what makes this profession so exciting!</p>



<p class="wp-block-paragraph">At <a href="https://www.dbi-services.com/company/" target="_blank" rel="noreferrer noopener">dbi services</a>, knowledge sharing is deeply embedded in our culture. </p>



<p class="wp-block-paragraph">Over the past three months, I’ve had the opportunity to share my experience working on ECM projects for years.</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img loading="lazy" decoding="async" width="300" height="300" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/04/check-box-300x300.png" alt="ECM project lessons learned" class="wp-image-37936" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/04/check-box-300x300.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/04/check-box-150x150.png 150w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/04/check-box-768x768.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/04/check-box.png 796w" sizes="auto, (max-width: 300px) 100vw, 300px" /></figure>
</div>


<p class="wp-block-paragraph">This post concludes the series by highlighting the key insights that have shaped my approach to these projects.</p>



<h2 id="h-stop-thinking-system-first" class="wp-block-heading">Stop thinking “System first”</h2>



<p class="wp-block-paragraph">In my previous roles, I was more of a product specialist than a solutions specialist. My job was to adapt clients&#8217; needs to the software framework.</p>



<p class="wp-block-paragraph">Now, working for a company that isn’t a “pure player” enables me to select the optimal solution from the beginning rather than having to adapt, of course I love <a href="https://www.m-files.com/" target="_blank" rel="noreferrer noopener">M-Files</a>, but <a href="https://www.hyland.com/en/solutions/products/alfresco-platform" target="_blank" rel="noreferrer noopener">alfresco</a> is another solution we like!</p>



<p class="wp-block-paragraph">For me, the right approach is certainly not:<br>&#8220;What can this ECM do?&#8221;</p>



<p class="wp-block-paragraph">Rather, it is:<br>&#8220;What business problems do we need to solve first, and for whom?&#8221;</p>



<p class="wp-block-paragraph">ECM initiatives often fail when they attempt to tackle everything at once rather than focusing on what truly matters. In practice, users don’t adopt tools just because they exist, they embrace solutions that directly address their daily pain points. That’s why achieving early, tangible success is critical. It builds credibility and helps secure continued investment.</p>



<p class="wp-block-paragraph">Rather than implementing broad, I would focus on three to five high-impact use cases, such as invoice processing, contract lifecycle management, and quality documentation. </p>



<p class="wp-block-paragraph">These cases should deliver measurable results within weeks rather than quarters. Each use case should be treated as its own product, with a clear value proposition and user-centric design, rather than as just another feature within a larger system.</p>



<h2 id="h-put-adoption-at-the-center" class="wp-block-heading">Put adoption at the center</h2>



<p class="wp-block-paragraph">I used to think: &#8220;If the solution is good, people will use it.&#8221;</p>



<p class="wp-block-paragraph">That’s wrong.</p>



<p class="wp-block-paragraph">Adoption requires preparation. It doesn&#8217;t just happen on its own.</p>



<p class="wp-block-paragraph">The hard truth is that the best ECM solution with no adoption equals failure.</p>



<p class="wp-block-paragraph">What I’d do differently:</p>



<ul class="wp-block-list">
<li>Identify the key users early on. They will help you get the solution adopted</li>



<li>Design in collaboration with actual users, not with their representatives.</li>



<li>Invest time and resources in on-boarding with in-app guidance, simple training paths, and internal champions.</li>
</ul>



<p class="wp-block-paragraph">Remember, if users need a manual to use the solution, you’ve already lost them.</p>



<h2 id="h-simplify-the-information-model" class="wp-block-heading">Simplify the information model</h2>



<p class="wp-block-paragraph">One of the biggest mistakes I’ve seen (and made) is overengineering metadata and taxonomy.</p>



<p class="wp-block-paragraph">We aimed for a perfect structure. We got complexity.</p>



<p class="wp-block-paragraph">The reality is that users don&#8217;t care about your taxonomy. It adds complexity, makes classification difficult, slows down their work, and ultimately reduces user adoption.</p>



<p class="wp-block-paragraph">Here&#8217;s what I&#8217;m doing now:</p>



<ul class="wp-block-list">
<li>I&#8217;m trying to limit the number of fields to seven or fewer.</li>



<li>I take full advantage of automation features, such as default values, smart classification, and recognition.</li>



<li>I use an iterative approach if it results in tangible improvements.</li>
</ul>



<p class="wp-block-paragraph">A good structure that is used consistently is better than a perfect one that nobody follows.</p>



<h2 id="h-design-for-automation" class="wp-block-heading">Design for automation</h2>



<p class="wp-block-paragraph">Projects often treat automation as a second phase. For me, that&#8217;s a mistake.</p>



<p class="wp-block-paragraph">Today, without automation, ECM is just a digital archive.</p>



<p class="wp-block-paragraph">Here are some things to do from day one:</p>



<ul class="wp-block-list">
<li>It is essential to pinpoint tasks that are repetitive in nature and convert them into workflows. Examples of such tasks include approvals, classification, team collaborations, and more. This conversion process must be incorporated into the initial release.</li>



<li>Use AI carefully and for meaningful topics. AI is trendy and can benefit us if we use it to accelerate work in areas such as classification, translation, and summarization, not just because it&#8217;s hype.</li>
</ul>



<p class="wp-block-paragraph">The goal is to eliminate unnecessary work and allow users to focus on what is important.</p>



<h2 id="h-measure-the-right-things" class="wp-block-heading">Measure the right things</h2>



<p class="wp-block-paragraph">Keep in mind that success metrics are not the number of documents migrated, users trained, or system uptime.</p>



<p class="wp-block-paragraph">True success is measured by the positive impact the solution brings, such as reduced processing time, increased adoption, improved compliance, and saved time.</p>



<p class="wp-block-paragraph">Measure the real impact to prove added value.</p>



<h2 id="h-treat-ecm-as-a-product-not-a-project" class="wp-block-heading">Treat ECM as a product, not a project</h2>



<p class="wp-block-paragraph">This is a common mistake that I still often see during ECM implementation, and it needs to change.<br>An ECM is not a static project consisting of analysis and implementation, and then it&#8217;s finished.</p>



<p class="wp-block-paragraph">We must adopt an agile approach of building, learning, improving, and repeating.</p>



<p class="wp-block-paragraph">As soon as users start using the solution, we must maintain a backlog of improvements, perform regular releases, and continuously gather user feedback.</p>



<p class="wp-block-paragraph">An ECM project is never truly finished because it must evolve with business needs. Otherwise, businesses will adapt their work to the tool and slowly abandon it.</p>



<h2 id="h-don-t-forget-the-governance" class="wp-block-heading">Don&#8217;t forget the governance</h2>



<p class="wp-block-paragraph">Although governance is essential, it can also become an obstacle.</p>



<p class="wp-block-paragraph">I’ve seen governance frameworks delay projects by several months because they lack flexibility.</p>



<p class="wp-block-paragraph">Nothing is perfect, so while you should meet compliance requirements, keep things simple.</p>



<p class="wp-block-paragraph">Clearly define responsibilities from the start:</p>



<ul class="wp-block-list">
<li>Who is responsible for metadata?</li>



<li>Who approves changes?</li>
</ul>



<p class="wp-block-paragraph">Ensure that governance remains light and practical.</p>



<p class="wp-block-paragraph">Strike the right balance between control and ease of use.</p>



<h2 id="h-think-about-who-you-re-doing-it-for" class="wp-block-heading">Think about who you&#8217;re doing it for.</h2>



<p class="wp-block-paragraph">Although IT leads this type of project, users are often not part of the team.</p>



<p class="wp-block-paragraph">Therefore, establishing strong collaboration between IT and business users is crucial.</p>



<p class="wp-block-paragraph">Involve users in the decision-making process.</p>



<p class="wp-block-paragraph">Hold them accountable for adoption, this is a company-wide project, and its success depends on them.</p>



<h2 id="h-the-platform-is-just-a-tool" class="wp-block-heading">The platform is just a tool</h2>



<p class="wp-block-paragraph">To sum up my years of experience in ECM.</p>



<p class="wp-block-paragraph">While it’s initially reassuring to master a product and understand its inner workings, ultimately, clients don’t care about that.</p>



<p class="wp-block-paragraph">They have various problems and want a solution and very often, the specific product doesn&#8217;t matter.</p>



<p class="wp-block-paragraph">They count on us to recommend the most suitable solution because they are busy running their business and don’t have time to compare products on the market.</p>



<p class="wp-block-paragraph">ECM success isn&#8217;t just about managing documents; it&#8217;s about enabling better work.</p>



<ul class="wp-block-list">
<li>Help users work more efficiently.</li>



<li>Provide business value.</li>



<li>Improve the user experience over time.</li>
</ul>



<p class="wp-block-paragraph">If you&#8217;re about to start a project, ask yourself:</p>



<ul class="wp-block-list">
<li>Are we solving real problems?</li>



<li>Are users involved from day one?</li>



<li>Are we delivering value early on?</li>
</ul>



<p class="wp-block-paragraph">If not, now is the perfect time to <a href="https://www.dbi-services.com/expertises/digitalization-with-ecm/" target="_blank" rel="noreferrer noopener">ask us</a> for help!</p>



<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/after-years-of-ecm-projects-heres-how-i-do-things-differently-nowadays/">After years of ECM projects, here’s how I do things differently nowadays</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/after-years-of-ecm-projects-heres-how-i-do-things-differently-nowadays/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>M-Files BD &#8211; Aggregations, reducers and series</title>
		<link>https://www.dbi-services.com/blog/m-files-bd-aggregations-reducers-and-series/</link>
					<comments>https://www.dbi-services.com/blog/m-files-bd-aggregations-reducers-and-series/#respond</comments>
		
		<dc:creator><![CDATA[Morgan Patou]]></dc:creator>
		<pubDate>Tue, 23 Jun 2026 22:38:36 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[Aggregation]]></category>
		<category><![CDATA[Business Dashboard]]></category>
		<category><![CDATA[M-Files]]></category>
		<category><![CDATA[Reducer]]></category>
		<category><![CDATA[Series]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45206</guid>

					<description><![CDATA[<p>In the previous post, I walked through the query side of the dashboard JSON: objectType, class, filters, date tokens. What I deliberately left out was the aggregation block, because it deserves its own post. The aggregation is what transforms the set of matching objects into a value the widget can render. There are five aggregation [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-bd-aggregations-reducers-and-series/">M-Files BD &#8211; Aggregations, reducers and series</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the <a href="https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/" target="_blank" rel="noreferrer noopener">previous post</a>, I walked through the query side of the dashboard JSON: <strong><em>objectType</em></strong>, <strong><em>class</em></strong>, <strong><em>filters</em></strong>, <strong><em>date tokens</em></strong>. What I deliberately left out was the <strong><em>aggregation</em></strong> block, because it deserves its own post.</p>



<p class="wp-block-paragraph">The aggregation is what transforms the set of matching objects into a value the widget can render. There are five aggregation types, six reducers, and one optional second dimension (<strong><em>seriesProperty</em></strong>). Together, they cover every widget shape from a single KPI number to a cross-tab pivot table.</p>



<h2 id="h-1-the-two-dimensional-model" class="wp-block-heading">1. The two-dimensional model</h2>



<p class="wp-block-paragraph">The aggregation has two complementary components:</p>



<ul class="wp-block-list">
<li>The aggregation <strong><em>type</em></strong> is the <strong>shape</strong> of the result: one value (<strong><em>summary</em></strong>), one value per group (<strong><em>groupByProperty</em></strong>), one value per time bucket (<strong><em>groupByDateBucket</em></strong>), one value per admin-defined range (<strong><em>groupByRange</em></strong>), or a simple list of objects (<strong><em>list</em></strong>).</li>



<li>The aggregation <strong><em>reducer</em></strong> is the <strong>operation</strong> applied within each group (or over the whole matching set for <strong><em>summary</em></strong>): <strong><em>count</em></strong> (default), <strong><em>sum</em></strong>, <strong><em>avg</em></strong>, <strong><em>min</em></strong>, <strong><em>max</em></strong>, <strong><em>median</em></strong>. Note: The reducer is ignored for <strong><em>list</em></strong>.</li>
</ul>



<p class="wp-block-paragraph">In other words, <strong><em>type</em></strong> decides whether you get a number, a chart, or a table; <strong><em>reducer</em></strong> decides what that number, bar, or cell actually measures.</p>



<h2 id="h-2-the-five-aggregation-types" class="wp-block-heading">2. The five aggregation types</h2>



<h3 id="h-2-1-summary-one-value-over-everything" class="wp-block-heading">2.1. summary &#8211; one value over everything</h3>



<p class="wp-block-paragraph"><strong><em>summary</em></strong> reduces the entire matching set into a single value. By default it counts the matching objects. However, with a different reducer, you can make it compute a property aggregate in different ways. Here are a few example of summary aggregations:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
// Total count of matching objects
&quot;aggregation&quot;: { &quot;type&quot;: &quot;summary&quot; }

// Total revenue of matching objects
// (sum all values from the &quot;Amount&quot; property)
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;summary&quot;,
  &quot;reducer&quot;: &quot;sum&quot;,
  &quot;reducerProperty&quot;: &quot;Amount&quot;
}

// Latest contract expiry date
// (display only the date with the highest value - drill-through still list all objects)
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;summary&quot;,
  &quot;reducer&quot;: &quot;max&quot;,
  &quot;reducerProperty&quot;: &quot;Effective through&quot;
}
</pre></div>


<p class="wp-block-paragraph">The widgets that accept <strong><em>summary</em></strong> are <strong><em>kpiNumber</em></strong>, <strong><em>gauge</em></strong>, and <strong><em>table</em></strong>. If you followed this series, you probably saw a bunch of the first two, already. The last one, in this case, will render the value as a one-row table. For all other chart widgets (donut, bar, line, area), <strong><em>summary</em></strong> does not really make visual sense, as a single value cannot be plotted on an X-Y axis.</p>



<h3 id="h-2-2-groupbyproperty-one-value-per-group" class="wp-block-heading">2.2. groupByProperty &#8211; one value per group</h3>



<p class="wp-block-paragraph"><strong><em>groupByProperty</em></strong> groups objects by the distinct values of a property (the <strong><em>propertyName</em></strong>) and applies the reducer to each group independently. Here are two examples:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
// Count of matching objects per Agreement type
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;groupByProperty&quot;,
  &quot;propertyName&quot;: &quot;Agreement type&quot;,
  &quot;includeEmptyResults&quot;: &quot;No&quot;
}

// Total revenue of matching objects per Customer
// (sum all values from the &quot;Amount&quot; property for each Customer independently)
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;groupByProperty&quot;,
  &quot;propertyName&quot;: &quot;Customer&quot;,
  &quot;reducer&quot;: &quot;sum&quot;,
  &quot;reducerProperty&quot;: &quot;Amount&quot;
}
</pre></div>


<p class="wp-block-paragraph">The supported fields are the following ones:</p>



<figure class="wp-block-table"><table><thead><tr><th>Field</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><em>propertyName</em></strong></td><td>Yes</td><td>Property to group by (any type is supported)</td></tr><tr><td><strong><em>reducer</em></strong></td><td>No</td><td>Defaults to <strong><em>count</em></strong> (c.f. section 1 above)</td></tr><tr><td><strong><em>reducerProperty</em></strong></td><td>Yes, when reducer != count</td><td>Property to reduce within each group. Can be the same as <strong><em>propertyName</em></strong> but it can also be different (c.f. above)</td></tr><tr><td><strong><em>includeEmptyResults</em></strong></td><td>No</td><td>When set to <strong><em>&#8220;Yes&#8221;</em></strong>, it adds a <strong><em>(none)</em></strong> group which will contain objects without value (e.g. no value for &#8220;Customer&#8221; property)</td></tr><tr><td><strong><em>seriesProperty</em></strong></td><td>No</td><td>Splits the chart into multiple series (c.f. section 4 below)</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">The widgets that accept <strong><em>groupByProperty</em></strong> are <strong><em>donut</em></strong>, <strong><em>bar</em></strong>, <strong><em>line</em></strong>, <strong><em>area</em></strong> and <strong><em>table</em></strong>. Basically, all charts widgets, plus the table which is kind of a Swiss knife, that works with everything.</p>



<h3 id="h-2-3-groupbydatebucket-one-value-per-time-period" class="wp-block-heading">2.3. groupByDateBucket &#8211; one value per time period</h3>



<p class="wp-block-paragraph">It is very similar to the <strong><em>groupByProperty</em></strong>, but the target must be a date / timestamp. Basically, something that contains a date, whether its only the date or a full date-time is fine. Because dates would probably be a bit too wide, there is a concept of buckets, to group dates by a pre-defined range that might make sense. The default time periods are <strong><em>day</em></strong>, <strong><em>week</em></strong>, <strong><em>month</em></strong>, <strong><em>quarter</em></strong> or <strong><em>year</em></strong>. Here are two examples:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
// Count of contracts expiring per month
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;groupByDateBucket&quot;,
  &quot;propertyName&quot;: &quot;Effective through&quot;,
  &quot;bucketSize&quot;: &quot;month&quot;,
  &quot;includeEmptyResults&quot;: &quot;Yes&quot;
}

// Sum of invoice amounts per quarter
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;groupByDateBucket&quot;,
  &quot;propertyName&quot;: &quot;Invoice date&quot;,
  &quot;bucketSize&quot;: &quot;quarter&quot;,
  &quot;reducer&quot;: &quot;sum&quot;,
  &quot;reducerProperty&quot;: &quot;Amount&quot;
}
</pre></div>


<p class="wp-block-paragraph">The supported fields are pretty similar to the <strong><em>groupByProperty</em></strong>:</p>



<figure class="wp-block-table"><table><thead><tr><th>Field</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><em>propertyName</em></strong></td><td>Yes</td><td>Property to group by (date / timestamp only)</td></tr><tr><td><strong><em>bucketSize</em></strong></td><td>No</td><td>Defaults to <strong><em>month</em></strong>, the size of the range to group by</td></tr><tr><td><strong><em>reducer</em></strong></td><td>No</td><td>Same as <strong><em>groupByProperty</em></strong></td></tr><tr><td><strong><em>reducerProperty</em></strong></td><td>Yes, when reducer != count</td><td>Same as <strong><em>groupByProperty</em></strong></td></tr><tr><td><strong><em>includeEmptyResults</em></strong></td><td>No</td><td>Same as <strong><em>groupByProperty</em></strong>, but <strong><em>&#8220;Yes&#8221;</em></strong> will also fill gaps with zero values (e.g. a month without revenue is still displayed as <strong><em>&#8220;0&#8221;</em></strong>, it&#8217;s not silently ignored)</td></tr><tr><td><strong><em>seriesProperty</em></strong></td><td>No</td><td>Same as <strong><em>groupByProperty</em></strong></td></tr></tbody></table></figure>



<p class="wp-block-paragraph"><strong><em>Note:</em></strong> you would usually combine <strong><em>groupByDateBucket</em></strong> with a date filter to limit the range of results. Without filters, the chart would show everything from the earliest object in the vault to the most recent, possibly spanning decades. If that&#8217;s what you want to see, then that&#8217;s absolutely fine. However, most of the time, a filter like <strong><em>between @startOfYear and @endOfYear</em></strong> for an annual trend chart might be more appropriate.</p>



<h3 id="h-2-4-groupbyrange-one-value-per-admin-defined-range" class="wp-block-heading">2.4. groupByRange &#8211; one value per admin-defined range</h3>



<p class="wp-block-paragraph">This one is also very similar to the last two groupings. With the main difference that this is the only one that allows you to define the exact range.</p>



<h4 id="h-2-4-1-the-groupbyrange-itself" class="wp-block-heading">2.4.1 The groupByRange itself</h4>



<p class="wp-block-paragraph">If you have a certain property that has a high cardinality, it might be difficult to display it with a <strong><em>groupByProperty</em></strong>. Let&#8217;s take for example the &#8220;Amount&#8221; property from before. When you want to apply math on it (sum/avg/min/max/median), then that&#8217;s fine because it only returns one value. But if you want to see the revenue themselves, without a prior grouping on something else (e.g. above we first group by &#8220;Customer&#8221;), then you would end-up with dozens/hundreds/thousands of groups? That&#8217;s where <strong><em>groupByRange</em></strong> shines, because you define the grouping (e.g. 0-1&#8217;000, 1&#8217;000-5&#8217;000, &gt;=5&#8217;000).</p>



<p class="wp-block-paragraph">You can use that grouping method with numeric / time / text / lookup properties. On the other hand, date / timestamp and boolean aren&#8217;t supported. The reason for that is simple: there is already <strong><em>groupByDateBucket</em></strong> for date / timestamp, and boolean can only have 2 values (Yes / No), so <strong><em>groupByProperty</em></strong> works just fine.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
// Invoices by specific range
// 3 ranges: 0-1000, 1000-5000, 5000-10000
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;groupByRange&quot;,
  &quot;propertyName&quot;: &quot;Amount&quot;,
  &quot;boundaries&quot;: &#x5B;&quot;0&quot;, &quot;1000&quot;, &quot;5000&quot;, &quot;10000&quot;]
}

// Invoices by specific range, with open ranges
// 4 ranges: 0-1000, 1000-5000, 5000-10000, &gt;=10000
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;groupByRange&quot;,
  &quot;propertyName&quot;: &quot;Amount&quot;,
  &quot;boundaries&quot;: &#x5B;&quot;*&quot;, &quot;1000&quot;, &quot;5000&quot;, &quot;10000&quot;, &quot;*&quot;]
}

// Efficiency / speed of processing / duration of some actions / etc...
// 4 ranges: 0-30s, 30s-1min, 1min-2min, &gt;=2min
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;groupByRange&quot;,
  &quot;propertyName&quot;: &quot;Duration&quot;,
  &quot;boundaries&quot;: &#x5B;&quot;*&quot;, &quot;00:00:30&quot;, &quot;00:01:00&quot;, &quot;00:02:00&quot;, &quot;*&quot;]
}

// Customers by country name
// 3 ranges: A-F, F-M, &gt;=M
// e.g. &quot;France&quot; in 2nd group, Switzerland in 3rd group
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;groupByRange&quot;,
  &quot;propertyName&quot;: &quot;Country&quot;,
  &quot;boundaries&quot;: &#x5B;&quot;A&quot;, &quot;F&quot;, &quot;M&quot;, &quot;*&quot;],
  &quot;reducer&quot;: &quot;count&quot;
}
</pre></div>


<p class="wp-block-paragraph">Again, the supported fields are fairly similar to the <strong><em>groupByProperty</em></strong>:</p>



<figure class="wp-block-table"><table><thead><tr><th>Field</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><em>propertyName</em></strong></td><td>Yes</td><td>Property to group by (numeric / time / text / lookup only)</td></tr><tr><td><strong><em>boundaries</em></strong></td><td>Yes</td><td><strong>Ordered</strong> array of range boundary values (at least 2 values, sorted ascending, with at least 1 non &#8220;*&#8221; value)</td></tr><tr><td><strong><em>reducer</em></strong></td><td>No</td><td>Same as <strong><em>groupByProperty</em></strong></td></tr><tr><td><strong><em>reducerProperty</em></strong></td><td>Yes, when reducer != count</td><td>Same as <strong><em>groupByProperty</em></strong></td></tr><tr><td><strong><em>includeEmptyResults</em></strong></td><td>No</td><td>Same as <strong><em>groupByProperty</em></strong>, but <strong><em>&#8220;Yes&#8221;</em></strong> will also show empty ranges</td></tr><tr><td><strong><em>seriesProperty</em></strong></td><td>No</td><td>Same as <strong><em>groupByProperty</em></strong></td></tr></tbody></table></figure>



<h4 id="h-2-4-2-how-boundaries-work" class="wp-block-heading">2.4.2. How boundaries work</h4>



<p class="wp-block-paragraph">Each boundary value marks the inclusive lower bound of a range and the exclusive upper bound of the range below it, except for the last range, which is fully inclusive. For example, <code>["0", "1000", "5000", "10000"]</code> creates three buckets: <code>[0, 1000)</code>, <code>[1000, 5000)</code> and <code>[5000, 10000]</code>. This means that a value of &#8220;1000&#8221; will end-up on the 2nd bucket only. A value of &#8220;5000&#8221; or &#8220;10000&#8221; will end-up on the 3rd bucket.</p>



<p class="wp-block-paragraph">In addition, as you can see in the examples above, you can use a wildcard (<code>"*"</code>) on either end: a leading <code>"*"</code> creates a bucket for everything below the first boundary, and a trailing <code>"*"</code> creates a bucket for everything at or above the last boundary.</p>



<h3 id="h-2-5-list-one-row-per-object" class="wp-block-heading">2.5. list &#8211; one row per object</h3>



<p class="wp-block-paragraph"><strong><em>list</em></strong> are pretty similar to search results from M-Files, in the sense that it will just list something, with pre-defined columns. When using this aggregation type, the reducers have no effect, because it only lists objects but do not apply any modifications / computing on them.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
// List all contracts with 3 specific columns
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;list&quot;,
  &quot;displayProperties&quot;: &#x5B;&quot;Agreement type&quot;, &quot;Effective through&quot;, &quot;Responsible person&quot;]
}
</pre></div>


<figure class="wp-block-table"><table><thead><tr><th>Field</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td><strong><em>displayProperties</em></strong></td><td>No, but highly recommended</td><td>Name of properties to include in the table, as columns, in addition to the object name</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">For simple lists, the objects will be pre-sorted alphabetically but the user is then able to re-sort them, by each of the columns displayed. When <strong><em>drillThroughEnabled</em></strong> is set to <strong><em>&#8220;Yes&#8221;</em></strong>, then table rows become clickable and allows navigation to the object in question. There is no modal/drill-through in this case, since the table list already display the target object (no grouping).</p>



<h2 id="h-3-the-six-reducers" class="wp-block-heading">3. The six reducers</h2>



<p class="wp-block-paragraph">As mentioned, all five aggregation types, except <strong><em>list</em></strong>, accept a <strong><em>reducer</em></strong>. You probably understand them already, but just as a quick table:</p>



<figure class="wp-block-table"><table><thead><tr><th>Reducer</th><th>What it computes</th><th>reducerProperty types</th><th>Empty set returns</th></tr></thead><tbody><tr><td><strong><em>count</em></strong> <em>(default)</em></td><td>Number of matching objects</td><td>n/a</td><td><strong><em>0</em></strong></td></tr><tr><td><strong><em>sum</em></strong></td><td>Total of the property&#8217;s values</td><td>Numeric or time</td><td><strong><em>null</em></strong> (rendered as <strong><em>&#8211;</em></strong>)</td></tr><tr><td><strong><em>avg</em></strong></td><td>Arithmetic mean</td><td>Numeric or time</td><td><strong><em>null</em></strong> (rendered as <strong><em>&#8211;</em></strong>)</td></tr><tr><td><strong><em>median</em></strong></td><td>Middle value</td><td>Numeric or time</td><td><strong><em>null</em></strong> (rendered as <strong><em>&#8211;</em></strong>)</td></tr><tr><td><strong><em>min</em></strong></td><td>Smallest value</td><td>Numeric or date / timestamp / time</td><td><strong><em>null</em></strong> (rendered as <strong><em>&#8211;</em></strong>)</td></tr><tr><td><strong><em>max</em></strong></td><td>Largest value</td><td>Numeric or date / timestamp / time</td><td><strong><em>null</em></strong> (rendered as <strong><em>&#8211;</em></strong>)</td></tr></tbody></table></figure>



<h3 id="h-3-1-the-date-time-valued-reducer-rule" class="wp-block-heading">3.1. The date/time-valued reducer rule</h3>



<p class="wp-block-paragraph">When <strong><em>min</em></strong> or <strong><em>max</em></strong> is applied to a date, timestamp, or time property, the reducer returns the value and it will be formatted for end-users based on their localization / regional settings: e.g. <strong><em>DD/MM/YYYY</em></strong> for dates, <strong><em>DD/MM/YYYY HH:mm</em></strong> for timestamps (minute precision), and <strong><em>HH:mm:ss</em></strong> for times.</p>



<p class="wp-block-paragraph">When <strong><em>sum</em></strong>, <strong><em>avg</em></strong> or <strong><em>median</em></strong> is applied to a time property, it allows you to compute a total (or average/median) duration for a certain activity. This might be useful if you have time-constraints.</p>



<p class="wp-block-paragraph">Three widgets can render date/time values: <strong><em>kpiNumber</em></strong> (a single big number), <strong><em>gauge</em></strong> (switch to date mode, covered in <a href="https://www.dbi-services.com/blog/m-files-bd-scalar-widgets-kpinumber-and-gauge/" target="_blank" rel="noreferrer noopener">Post 4a</a>) and <strong><em>table</em></strong> (simple display in rows).</p>



<h2 id="h-4-seriesproperty-the-second-dimension" class="wp-block-heading">4. seriesProperty &#8211; the second dimension</h2>



<p class="wp-block-paragraph">The series details were already covered a bit in the posts <a href="https://www.dbi-services.com/blog/m-files-bd-trend-widgets-line-and-area/" target="_blank" rel="noreferrer noopener">4b</a> and <a href="https://www.dbi-services.com/blog/m-files-bd-distribution-and-tabular-widgets-donut-bar-table/" target="_blank" rel="noreferrer noopener">4c</a>. But, this is the feature that turns a single-series widget into a multi-actor comparison. When you set a <strong><em>seriesProperty</em></strong> on a <strong><em>groupBy</em></strong> aggregation, the engine will automatically produce one series per distinct value of the series property. This allows a two-dimensional comparison.</p>



<p class="wp-block-paragraph">The behavior per widget type is the following:</p>



<ul class="wp-block-list">
<li><strong><em>line</em></strong> / <strong><em>area</em></strong> &#8211; one colored line per series, with an auto-generated legend.</li>



<li><strong><em>bar</em></strong> &#8211; one colored sub-bar per series (<strong><em>display.barLayout</em></strong> controls stacked vs grouped).</li>



<li><strong><em>donut</em></strong> &#8211; a multi-mini-pie grid, one donut per series, with a shared legend.</li>



<li><strong><em>table</em></strong> &#8211; a cross-tab pivot, one column per series.</li>
</ul>



<p class="wp-block-paragraph">As a reminder, <strong><em>kpiNumber</em></strong> and <strong><em>gauge</em></strong> ignore <strong><em>seriesProperty</em></strong>, since they only display single-values.</p>



<h3 id="h-4-1-use-low-cardinality-series-only" class="wp-block-heading">4.1. Use low-cardinality series only</h3>



<p class="wp-block-paragraph">I repeated this in every widget post but it is worth restating: <strong><em>seriesProperty</em></strong> should be <strong>low-cardinality</strong>. A property with five distinct values produces a readable multi-series chart. A property with two hundred values produces a colored mess. In that case, you might want to use a <strong><em>groupByRange</em></strong>, to reduce the amount of groups and therefore the series.</p>



<h3 id="h-4-2-includeemptyresults-in-multi-series" class="wp-block-heading">4.2. includeEmptyResults in multi-series</h3>



<p class="wp-block-paragraph">In single-series mode, <strong><em>includeEmptyResults: &#8220;Yes&#8221;</em></strong> fills empty time buckets with zero values. In multi-series mode, it does the same <strong>across both dimensions</strong>: every series gets a zero in any bucket where it has no data. This avoids broken lines and visually confusing gaps.</p>



<p class="wp-block-paragraph">The behavior also adds a <strong><em>(none)</em></strong> bucket for objects whose primary group property has no value, and a <strong><em>(none)</em></strong> series for objects whose series property has no value. These are appended at the end so it doesn&#8217;t disrupt the &#8220;main story&#8221;.</p>



<h3 id="h-4-3-multi-select-lookups-in-seriesproperty-and-propertyname" class="wp-block-heading">4.3. Multi-select lookups in seriesProperty (and propertyName)</h3>



<p class="wp-block-paragraph">A subtle but important case: as you probably know, M-Files has a <strong>multi-select lookup</strong> property type. These allow the selection of multiple pre-defined values. Because of that, objects with multiple values will end-up in multiple buckets/groups, with the &#8220;counted once per value&#8221; rule.</p>



<p class="wp-block-paragraph">Example: a customer with office locations in Geneva, Zurich and Berlin could appear three times, once for a Geneva bucket, once for a Zurich bucket and finally once for a Berlin bucket. The total of all bucket counts can therefore exceed the total number of objects when some objects have multiple values.</p>



<p class="wp-block-paragraph">This is the correct and expected behavior for multi-select lookups. The alternative (counting each object only in its first value) would silently hide the multi-value relationships that often matter most.</p>



<h2 id="h-5-displayproperties-on-drill-through" class="wp-block-heading">5. displayProperties on drill-through</h2>



<p class="wp-block-paragraph">I mentioned <strong><em>displayProperties</em></strong> in section 2.5 above, as optional column to be added for <strong><em>list</em></strong> aggregations. The same field has a second role for all other aggregation type (<strong><em>summary</em></strong>, <strong><em>groupByProperty</em></strong>, <strong><em>groupByDateBucket</em></strong>, <strong><em>groupByRange</em></strong>): it controls <strong>the columns in the drill-through modal</strong>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
&quot;aggregation&quot;: {
  &quot;type&quot;: &quot;groupByProperty&quot;,
  &quot;propertyName&quot;: &quot;Agreement type&quot;,
  &quot;displayProperties&quot;: &#x5B;&quot;Effective through&quot;, &quot;Responsible person&quot;]
}
</pre></div>


<p class="wp-block-paragraph">When the user clicks a donut slice (or a bar, or a row in a count table), the drill-through modal shows one row per object in that group, with the object name plus all the optional columns defined in the <strong><em>displayProperties</em></strong> value (e.g. <strong><em>Effective through</em></strong> and <strong><em>Responsible person</em></strong>).</p>



<h2 id="h-6-the-compatibility-cheat-sheet" class="wp-block-heading">6. The compatibility cheat sheet</h2>



<p class="wp-block-paragraph">I already put this table at the end of <a href="https://www.dbi-services.com/blog/m-files-bd-distribution-and-tabular-widgets-donut-bar-table/" target="_blank" rel="noreferrer noopener">Post 4c</a>, but it is short enough, so:</p>



<figure class="wp-block-table"><table><thead><tr><th>Widget type</th><th>summary</th><th>groupByProperty</th><th>groupByDateBucket</th><th>groupByRange</th><th>list</th><th>seriesProperty</th></tr></thead><tbody><tr><td><strong><em>kpiNumber</em></strong></td><td>yes</td><td>&#8211;</td><td>&#8211;</td><td>&#8211;</td><td>&#8211;</td><td>ignored</td></tr><tr><td><strong><em>gauge</em></strong></td><td>yes</td><td>&#8211;</td><td>&#8211;</td><td>&#8211;</td><td>&#8211;</td><td>ignored</td></tr><tr><td><strong><em>donut</em></strong></td><td>&#8211;</td><td>yes</td><td>yes</td><td>yes</td><td>&#8211;</td><td>multi-mini-pie</td></tr><tr><td><strong><em>bar</em></strong></td><td>&#8211;</td><td>yes</td><td>yes</td><td>yes</td><td>&#8211;</td><td>stacked or grouped</td></tr><tr><td><strong><em>line</em></strong></td><td>&#8211;</td><td>yes</td><td>yes</td><td>yes</td><td>&#8211;</td><td>multi-series lines</td></tr><tr><td><strong><em>area</em></strong></td><td>&#8211;</td><td>yes</td><td>yes</td><td>yes</td><td>&#8211;</td><td>multi-series areas</td></tr><tr><td><strong><em>table</em></strong></td><td>yes</td><td>yes</td><td>yes</td><td>yes</td><td>yes</td><td>cross-tab pivot</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Combine this with the reducer table in section 3 and you have the full answer to &#8220;can I use aggregation X with widget Y, and with reducer Z on property type T&#8221;. In any case, the Visual Designer and the validation process will prevent you to make any mistake.</p>



<h2 id="h-7-what-this-gives-you" class="wp-block-heading">7. What this gives you</h2>



<p class="wp-block-paragraph">The query side (<a href="https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/" target="_blank" rel="noreferrer noopener">Post 5</a>) plus the aggregation side (this post) together cover everything the engine supports. If that wasn&#8217;t the case before, you should now be able to read and understand every line from any of the previous JSON example.</p>



<p class="wp-block-paragraph">The combinations are richer than they look at first. A <strong><em>groupByDateBucket</em></strong> on monthly invoices with a <strong><em>sum</em></strong> reducer on <strong><em>Amount</em></strong> and a <strong><em>seriesProperty</em></strong> on <strong><em>Customer</em></strong>, rendered as a <strong><em>line</em></strong> widget with <strong><em>includeEmptyResults: &#8220;Yes&#8221;</em></strong>, gives a multi-customer revenue trend that takes about 15 lines of JSON. A <strong><em>groupByProperty</em></strong> on <strong><em>Agreement type</em></strong> with a <strong><em>seriesProperty</em></strong> on <strong><em>Workflow state</em></strong> rendered as a <strong><em>table</em></strong> gives a cross-tab pivot with drill-through on every cell.</p>



<p class="wp-block-paragraph">The possibilities aren&#8217;t endless, obviously, but good luck if you would like to try them all&#8230; Last time I checked, you could create several million different widget combinations. An important part of that would trigger warnings or errors for non-supported cases, but still a considerable scale.</p>



<p class="wp-block-paragraph">So far, I covered the end-user part, the JSON, the widgets and now the queries. These are the building blocks of dashboards. The remaining posts of the series will cover:</p>



<ul class="wp-block-list">
<li><a href="https://www.dbi-services.com/blog/m-files-bd-the-admin-part/" id="45312" target="_blank" rel="noreferrer noopener"><strong>Post 7</strong></a> &#8211; The Admin tab: the actions, Visual Designer / JSON editor, the two-stage validator, import / export, access control.</li>



<li><strong><a href="https://www.dbi-services.com/blog/m-files-bd-putting-it-together-with-the-visual-designer/" id="45433" target="_blank" rel="noreferrer noopener">Post 8</a></strong> &#8211; Building a dashboard with the Visual Designer.</li>
</ul>



<p class="wp-block-paragraph">Want to know more about this Business Dashboard? <a href="https://www.dbi-services.com/company/contact/" target="_blank" rel="noreferrer noopener">Contact us</a> and we will be happy to showcase it on <a href="https://www.m-files.com/" target="_blank" rel="noreferrer noopener">M-Files</a>.</p>



<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-bd-aggregations-reducers-and-series/">M-Files BD &#8211; Aggregations, reducers and series</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/m-files-bd-aggregations-reducers-and-series/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>M-Files BD &#8211; Queries: objectType, class, filters, date tokens</title>
		<link>https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/</link>
					<comments>https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/#respond</comments>
		
		<dc:creator><![CDATA[Morgan Patou]]></dc:creator>
		<pubDate>Sat, 20 Jun 2026 16:32:18 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[Business Dashboard]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[dateToken]]></category>
		<category><![CDATA[Filters]]></category>
		<category><![CDATA[M-Files]]></category>
		<category><![CDATA[objectType]]></category>
		<category><![CDATA[query]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45175</guid>

					<description><![CDATA[<p>In the previous posts of this series, I covered the anatomy of a dashboard definition and the seven widget types (KPI &#38; gauge, line &#38; area, donut, bar &#38; table) the engine supports, as of now. In this one, we will go through the Business Dashboard queries, i.e. the query section that I pretty much [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/">M-Files BD &#8211; Queries: objectType, class, filters, date tokens</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the previous posts of this series, I covered the <a href="https://www.dbi-services.com/blog/m-files-bd-anatomy-of-a-dashboard-definition/" target="_blank" rel="noreferrer noopener">anatomy of a dashboard definition</a> and the seven widget types (<a href="https://www.dbi-services.com/blog/m-files-bd-scalar-widgets-kpinumber-and-gauge/" target="_blank" rel="noreferrer noopener">KPI &amp; gauge</a>, <a href="https://www.dbi-services.com/blog/m-files-bd-trend-widgets-line-and-area/" target="_blank" rel="noreferrer noopener">line &amp; area</a>, <a href="https://www.dbi-services.com/blog/m-files-bd-distribution-and-tabular-widgets-donut-bar-table/" target="_blank" rel="noreferrer noopener">donut, bar &amp; table</a>) the engine supports, as of now. In this one, we will go through the Business Dashboard queries, i.e. the <strong><em>query</em></strong> section that I pretty much ignores so far. It is now time to look at it a bit more.</p>



<p class="wp-block-paragraph">A query has four parts: <strong><em>objectType</em></strong>, <strong><em>class</em></strong>, <strong><em>filters</em></strong>, and <strong><em>aggregation</em></strong>. This post covers the first three. The fourth (aggregations, including its reducers) is the topic of the next post.</p>



<p class="wp-block-paragraph">As mentioned before, the principle that drove the design of the Business Dashboard is to <strong>be generic</strong>. The engine never enumerates specific business values, it only translates the structured JSON query into a standard M-Files server search.</p>



<h2 id="h-1-objecttype-the-m-files-object-type-to-query" class="wp-block-heading">1. objectType &#8211; the M-Files object type to query</h2>



<p class="wp-block-paragraph">Every query starts with <strong><em>objectType</em></strong>. It is the M-Files object type the engine searches against, addressed by its display name (the singular form is fine, the engine resolves it and uses it).</p>



<h3 id="h-1-1-single-object-type" class="wp-block-heading">1.1. Single object type</h3>



<p class="wp-block-paragraph">The simplest form is a string:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
&quot;objectType&quot;: &quot;Document&quot;
</pre></div>


<p class="wp-block-paragraph">Or any other object type defined in your vault:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
// Looking for Customers
&quot;objectType&quot;: &quot;Customer&quot;

// Looking for Projects
&quot;objectType&quot;: &quot;Project&quot;

// Looking for Employees
&quot;objectType&quot;: &quot;Employee&quot;
</pre></div>


<p class="wp-block-paragraph">The display name is <strong>case-insensitive</strong> but must otherwise match what the vault shows. Please note that, if the vault is let&#8217;s say, in German, you might need to use &#8220;Dokument&#8221; and not &#8220;Document&#8221;. In short, you need to use what the vault defines/shows.</p>



<p class="wp-block-paragraph">If the name does not match, the widget shows a clear <strong><em>✗ Object type &#8216;xxx&#8217; not found in this vault</em></strong> error.</p>



<h3 id="h-1-2-multiple-object-types" class="wp-block-heading">1.2. Multiple object types</h3>



<p class="wp-block-paragraph">When the same logical entity exists across more than one M-Files object type (for example, a &#8220;Proposal&#8221; can be both a Document and a Document collection), you can pass an array:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
&quot;objectType&quot;: &#x5B;&quot;Document&quot;, &quot;Document collection&quot;]
</pre></div>


<p class="wp-block-paragraph">The engine resolves every name and builds a single search to find all matching objects. This behaves like the <strong><em>&#8220;is one of&#8221;</em></strong> filter in M-Files Advanced Search. Please note that the Drill-through will also inherit the same scope, automatically.</p>



<p class="wp-block-paragraph">A small but important detail: even in this case, the engine executes a single search. This matters for performance and for consistency (a single <strong><em>serverScanMaxResults</em></strong> cap applies, not two independent caps).</p>



<h2 id="h-2-class-narrowing-the-scope-and-the-perf-impact" class="wp-block-heading">2. class &#8211; narrowing the scope (and the perf impact)</h2>



<p class="wp-block-paragraph">The <strong><em>class</em></strong> field is optional but <strong><em>strongly</em></strong> recommended. It restricts the query to one specific class:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
&quot;objectType&quot;: &quot;Document&quot;,
&quot;class&quot;: &quot;Contract or Agreement&quot;
</pre></div>


<p class="wp-block-paragraph">Querying &#8220;all Documents&#8221; in a vault that contains 50&#8217;000 documents of which only 1&#8217;000 are Contracts is pure waste. Adding <strong><em>&#8220;class&#8221;: &#8220;Contract or Agreement&#8221;</em></strong> narrows the scan immediately, which both improves performance and makes the widget result more meaningful.</p>



<p class="wp-block-paragraph">Therefore, both M-Files Administrators and M-Files Users will thank you for selecting the right class to use. It avoids slowness, irrelevant results and reduces resource usage. You should always set a <strong><em>class</em></strong>, when possible.</p>



<p class="wp-block-paragraph">When <strong><em>objectType</em></strong> is an array and <strong><em>class</em></strong> is specified, the engine will find any object, from that class, from any of the object types listed. So the following will match Proposal-class objects from both types:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
&quot;objectType&quot;: &#x5B;&quot;Document&quot;, &quot;Document collection&quot;],
&quot;class&quot;: &quot;Proposal&quot;
</pre></div>


<p class="wp-block-paragraph">If the class is misspelled, the widget shows a <strong><em>✗ Class &#8216;xxx&#8217; not found on the specified object type(s)</em></strong> error. As with object types, the name depends on what the vault defines/shows.</p>



<h2 id="h-3-filters-the-and-combined-conditions" class="wp-block-heading">3. filters &#8211; the AND-combined conditions</h2>



<p class="wp-block-paragraph">The <strong><em>filters</em></strong> array, which is optional, contains zero or more conditions. If you specify multiple filters, then <strong>all filters must match</strong>. That means that M-Files applies a AND semantic between each filter. By the way, M-Files doesn&#8217;t directly support &#8220;OR&#8221; conditions, it always joins them. The only &#8220;kind-of-an-exception&#8221;, as far as I know, is the <strong><em>&#8220;is one of&#8221;</em></strong> where you can set multiple values from the Lookup/MultiSelectLookup property values. But that&#8217;s only a single condition, not multiple conditions.</p>



<p class="wp-block-paragraph">Here is an example of a filter:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
&quot;filters&quot;: &#x5B;
  { &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;,
    &quot;value&quot;: &quot;@today&quot;, &quot;valueType&quot;: &quot;dateToken&quot; },
  { &quot;property&quot;: &quot;Agreement type&quot;, &quot;operator&quot;: &quot;equals&quot;,
    &quot;value&quot;: &quot;Subcontracting Agreement&quot; }
]
</pre></div>


<p class="wp-block-paragraph">Each filter has up to four fields:</p>



<ul class="wp-block-list">
<li><strong><em>property</em></strong>: the property display name on which to apply the operator / value.</li>



<li><strong><em>operator</em></strong>: one of the operators listed in section 4 below.</li>



<li><strong><em>value</em></strong>: the value to use for the comparison with the property&#8217;s actual value. For the four &#8220;presence&#8221; operators (<strong><em>isEmpty</em></strong>, <strong><em>isNotEmpty</em></strong>, <strong><em>isPresentEmpty</em></strong>, <strong><em>isPresentNotEmpty</em></strong>), this parameter should NOT be defined. For the &#8220;begin-end&#8221; operators (<strong><em>between</em></strong> / <strong><em>notBetween</em></strong>, this parameter should be an array of two elements. For the &#8220;is one of&#8221; operators (<strong><em>inList</em></strong> / <strong><em>notInList</em></strong>), this parameter should be an array of at least two elements. Finally, in all other cases, it&#8217;s simply a string.</li>



<li><strong><em>valueType</em></strong>: either <strong><em>&#8220;literal&#8221;</em></strong> (default, it means to use the value as-is) or a <strong><em>&#8220;dateToken&#8221;</em></strong> (covered in section 5).</li>
</ul>



<h2 id="h-4-the-filter-operators" class="wp-block-heading">4. The filter operators</h2>



<p class="wp-block-paragraph">The engine supports a rich set of operators across two execution paths:</p>



<ul class="wp-block-list">
<li><strong>Native</strong>: runs server-side before the <strong><em>serverScanMaxResults</em></strong> cap is applied. Therefore, this is the preferred option, when possible.</li>



<li><strong>Post-filter</strong>: runs in memory after the server returns up to <strong><em>serverScanMaxResults</em></strong> objects. Therefore, this is correct and useful when you want to do something that M-Files doesn&#8217;t support out-of-the-box but that still makes sense for your Business use-case.</li>
</ul>



<p class="wp-block-paragraph">In short, whenever possible, prefer to apply a <strong><em>native</em></strong> filter. The main reason for this is simple. Let&#8217;s assume that you have 1&#8217;000 Contracts in the vault:</p>



<ul class="wp-block-list">
<li>If you apply a <strong><em>native</em></strong> filter, for example <strong><em>Effective through &gt;= @today</em></strong>, then if only 200 of them match that criteria, then M-Files will only return these 200 objects directly. There is no loss of performance here.</li>



<li>If you apply a <strong><em>post-filter</em></strong>, for example <strong><em>Effective through contains 2026-12</em></strong>, then M-Files will have no other choice than returning all 1&#8217;000 Contracts first. On top of that, the post-filter compares the value of Effective through and checks whether it contains &#8220;2026-12&#8221;. This is because the &#8220;contains&#8221; condition doesn&#8217;t exist in M-Files for Date properties. Therefore, we cannot use what doesn&#8217;t exist, but we still want to provide that possibility / logic, and therefore it is done in memory after returning all results. In that example, you get 5x more results and on top of it, you also need to check which ones match the expected value.</li>
</ul>



<p class="wp-block-paragraph">The performance difference between <strong><em>native</em></strong> and <strong><em>post-filter</em></strong> is imperceptible for small result sets (&lt;few hundreds), but you would probably feel it if you expect to fetch thousands of results. A great catch, if you need to apply a post-filter for a valid business reasons, is to first apply a native one, which highly reduces the result set, and then apply the post-filter one that you need. Also, don&#8217;t forget to specify a <strong><em>class</em></strong>!</p>



<p class="wp-block-paragraph">Then, let&#8217;s proceed with a deep-dive on the different operators (if you only want the &#8220;summary&#8221;, look at the end of section 4 for the cheat sheet). The 22 operators support all data types, without exceptions, contrary to M-Files operators which offer much less capabilities. The only distinction is, as mentioned above, whether the operator is native or post-filter.</p>



<h3 id="h-4-1-equals-and-notequal" class="wp-block-heading">4.1. equals and notEqual</h3>



<p class="wp-block-paragraph">As you would expect, these are for exact match. Only the MultiLineText properties are processed as post-filter.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Agreement type&quot;, &quot;operator&quot;: &quot;equals&quot;,
  &quot;value&quot;: &quot;Subcontracting Agreement&quot; }

{ &quot;property&quot;: &quot;Customer&quot;, &quot;operator&quot;: &quot;notEqual&quot;,
  &quot;value&quot;: &quot;ESTT Corporation (IT)&quot; }
</pre></div>


<p class="wp-block-paragraph">When using display names on Lookup properties (Lookup or MultiSelectLookup), as its the case in above example, the value lists are cached, so that each execution doesn&#8217;t need to re-fetch the things that it already knows of, and it can just use it directly, to ask M-Files what&#8217;s the updated count.</p>



<h3 id="h-4-2-lessthan-greaterthan-lessorequal-greaterorequal" class="wp-block-heading">4.2. lessThan, greaterThan, lessOrEqual, greaterOrEqual</h3>



<p class="wp-block-paragraph">These &#8220;range&#8221; operators support all property types except Boolean, because it doesn&#8217;t make any sense to apply a &#8220;lessThan&#8221; to a Boolean&#8230; In addition, and similarly to above, only the MultiLineText properties are processed as post-filter, everything else is native. Obviously, you can apply these operators on Date and Numeric values, but it also works with Text, Lookup or MultiSelectLookup. When it needs to work on Text-based properties, it does a lexicographic comparison (e.g. ABC &lt; ABD, ACE &gt; ABB).</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Due date&quot;, &quot;operator&quot;: &quot;lessThan&quot;,
  &quot;value&quot;: &quot;@today&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }

{ &quot;property&quot;: &quot;Amount&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;, &quot;value&quot;: 1000 }
</pre></div>


<h3 id="h-4-3-between-and-notbetween" class="wp-block-heading">4.3. between and notBetween</h3>



<p class="wp-block-paragraph">These as also &#8220;range&#8221; operators but I put them separately because the <strong><em>value</em></strong> must be a two-element array, as previously written. <strong><em>between</em></strong> is, otherwise, exactly the same as lessThan/greaterThan/lessOrEqual/greaterOrEqual. In the array, you would provide the begin and the end of the range. to fetch.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;between&quot;,
  &quot;value&quot;: &#x5B;&quot;@startOfYear&quot;, &quot;@endOfYear&quot;], &quot;valueType&quot;: &quot;dateToken&quot; }

{ &quot;property&quot;: &quot;Amount&quot;, &quot;operator&quot;: &quot;between&quot;, &quot;value&quot;: &#x5B;100, 1000] }
</pre></div>


<p class="wp-block-paragraph"><strong><em>notBetween</em></strong> is the opposite of <strong><em>between</em></strong>, obviously, but it&#8217;s a bit more than that&#8230; As previously mentioned, M-Files does NOT handle <strong><em>OR</em></strong> logic. But if you think about it, a &#8220;notBetween&#8221; is actually an OR, because you want values below the range OR above the range (<strong><em>value &lt; low OR value &gt; high</em></strong>). Because of that, <strong><em>notBetween</em></strong> is always a <strong>post-filter</strong>, without exception.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Amount&quot;, &quot;operator&quot;: &quot;notBetween&quot;, &quot;value&quot;: &#x5B;100, 1000] }
</pre></div>


<h3 id="h-4-4-isempty-isnotempty-ispresentempty-ispresentnotempty" class="wp-block-heading">4.4. isEmpty, isNotEmpty, isPresentEmpty, isPresentNotEmpty</h3>



<p class="wp-block-paragraph">These four operators test whether a property has a value, as the name suggests&#8230; However, there is a catch: M-Files only distinguish between &#8220;the property is present and empty&#8221; or &#8220;the property is present and non-empty&#8221;.</p>



<p class="wp-block-paragraph">You might have faced that with Templates for example. That&#8217;s a pretty common occurrence. In M-Files, there is a parameter &#8220;Is template&#8221; which indicates whether a specific object has been defined as a template. But that parameter is only present in a few select objects, it&#8217;s usualy not present on all of them. Therefore, if you search for &#8220;Is template &#8211; is empty&#8221;, you will most probably find 0 results, because M-Files only check for documents where the property is present and where it is empty.</p>



<p class="wp-block-paragraph">The distinction is simple but it matters a lot. That&#8217;s why in the Business Dashboard, the <strong><em>native</em></strong> M-Files &#8220;is empty&#8221; / &#8220;is not empty&#8221; have been renamed as <strong><em>isPresentEmpty</em></strong> and <strong><em>isPresentNotEmpty</em></strong>. These are the fully native option from M-Files, and therefore they run on the server-side.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;isPresentEmpty&quot; }

{ &quot;property&quot;: &quot;Responsible person&quot;, &quot;operator&quot;: &quot;isPresentNotEmpty&quot; }
</pre></div>


<p class="wp-block-paragraph">In addition, I also defined two other operators, <strong><em>isEmpty</em></strong> and <strong><em>isNotEmpty</em></strong>. These two are <strong>always post-filters</strong>, they scan all matching objects in memory after the server returns them:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;isEmpty&quot; }

{ &quot;property&quot;: &quot;Responsible person&quot;, &quot;operator&quot;: &quot;isNotEmpty&quot; }
</pre></div>


<p class="wp-block-paragraph">Because of that post-processing, <strong><em>isEmpty</em></strong> matches objects where the property is absent OR where it is present but empty. This allows a more &#8220;complete&#8221; result set, which might be required in some specific business use-cases.</p>



<p class="wp-block-paragraph"><strong><em>isNotEmpty</em></strong> matches objects where the property is present AND non-empty. You might think it is exactly the same as <strong><em>isPresentNotEmpty</em></strong>, right? Well, in 99% of the cases, yes it is the same (but slower, since done as post-filter)&#8230; Except when there are bugs in M-Files ;). While developing the Business Dashboard, I found a few bugs, including one with lexicographic processing on MultiSelectLookup properties. The usage of my own operator was giving me a slightly different result and while investigating why, I found the reason and the bug in M-Files&#8217;s own operator.</p>



<p class="wp-block-paragraph">In summary:</p>



<figure class="wp-block-table"><table><thead><tr><th>What you want to find</th><th>Operator</th></tr></thead><tbody><tr><td>Objects where the property is present and empty OR is completely absent</td><td><strong><em>isEmpty</em></strong> (post-filter)</td></tr><tr><td>Objects where the property is present and empty</td><td><strong><em>isPresentEmpty</em></strong> (native)</td></tr><tr><td>Objects where the property has a value</td><td><strong><em>isPresentNotEmpty</em></strong> (native)</td></tr><tr><td>Objects where the property has a value</td><td><strong><em>isNotEmpty</em></strong> (post-filter alternative &#8211; sometimes more accurate)</td></tr></tbody></table></figure>



<h3 id="h-4-5-inlist-and-notinlist" class="wp-block-heading">4.5. inList and notInList</h3>



<p class="wp-block-paragraph">As the name suggests, if you are looking for multiple values, <strong><em>inList</em></strong> is what you should use. It must be an array of at least 2 elements, but you can put 50 if you want to. M-Files only support Lookup for this one, natively. Therefore, all other property types are handled as post-filters.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Agreement type&quot;, &quot;operator&quot;: &quot;inList&quot;,
  &quot;value&quot;: &#x5B;&quot;Subcontracting Agreement&quot;, &quot;Project Agreement&quot;] }

{ &quot;property&quot;: &quot;Workflow state&quot;, &quot;operator&quot;: &quot;inList&quot;,
  &quot;value&quot;: &#x5B;&quot;In review&quot;] }
</pre></div>


<p class="wp-block-paragraph"><strong><em>notInList</em></strong> is simply the opposite, so it just excludes all elements provided. It supports exactly the same thing as inList and works in the same way too.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Workflow state&quot;, &quot;operator&quot;: &quot;notInList&quot;,
  &quot;value&quot;: &#x5B;&quot;Approved&quot;] }
</pre></div>


<p class="wp-block-paragraph">A subtle catch with &#8220;not&#8221; operators (<strong><em>notInList</em></strong> and similar): an object whose Lookup property is present but has no item selected satisfies &#8220;not in list&#8221; by default, because there is no value to match or compare with. If you don&#8217;t want to see these objects, then you can simply add a second filter on that same property with <strong><em>isPresentNotEmpty</em></strong>!</p>



<h3 id="h-4-6-contains-and-doesnotcontain" class="wp-block-heading">4.6. contains and doesNotContain</h3>



<p class="wp-block-paragraph"><strong><em>contains</em></strong> is a substring match (similar to <strong><em>matchesWildcardPattern</em></strong> (c.f. below) with implicit wildcards on both sides), it finds objects where the property value includes the given string anywhere inside.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Title&quot;, &quot;operator&quot;: &quot;contains&quot;, &quot;value&quot;: &quot;NDA&quot; }

{ &quot;property&quot;: &quot;Title&quot;, &quot;operator&quot;: &quot;doesNotContain&quot;,
  &quot;value&quot;: &quot;draft&quot; }
</pre></div>


<p class="wp-block-paragraph">For Text, MultiLineText and Lookup properties, both operators are <strong>native</strong>. The rest is supported as <strong>post-filters</strong>, comparing against the string representation.</p>



<h3 id="h-4-7-startswith-doesnotstartwith-endswith-doesnotendwith" class="wp-block-heading">4.7. startsWith, doesNotStartWith, endsWith, doesNotEndWith</h3>



<p class="wp-block-paragraph"><strong><em>startsWith</em></strong> and <strong><em>doesNotStartWith</em></strong> match objects based on the beginning of a property&#8217;s value. These are native only for Text and Lookup properties.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Name or title&quot;, &quot;operator&quot;: &quot;startsWith&quot;,
  &quot;value&quot;: &quot;PO-&quot;    }

{ &quot;property&quot;: &quot;Name or title&quot;, &quot;operator&quot;: &quot;doesNotStartWith&quot;,
  &quot;value&quot;: &quot;DRAFT-&quot; }
</pre></div>


<p class="wp-block-paragraph"><strong><em>endsWith</em></strong> and <strong><em>doesNotEndWith</em></strong> match based on the end of a property&#8217;s value. This doesn&#8217;t exist in M-Files, there is no equivalent and therefore, these are always <strong>post-filters</strong> for all property types.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Name or title&quot;, &quot;operator&quot;: &quot;endsWith&quot;,
  &quot;value&quot;: &quot;(final)&quot; }

{ &quot;property&quot;: &quot;Name or title&quot;, &quot;operator&quot;: &quot;doesNotEndWith&quot;,
  &quot;value&quot;: &quot;(draft)&quot; }
</pre></div>


<h3 id="h-4-8-matcheswildcardpattern-and-doesnotmatchwildcardpattern" class="wp-block-heading">4.8. matchesWildcardPattern and doesNotMatchWildcardPattern</h3>



<p class="wp-block-paragraph">These are the most expressive pattern operators. The <strong><em>value</em></strong> is a regex string where <strong><em>\</em></strong>* matches any number of characters and <strong><em>?</em></strong> matches exactly one character. This is pretty similar to the contains/startsWith/endsWith (and their opposite), obviously, but it is a bit more powerful if you need to match an exact pattern that you know of.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Title&quot;, &quot;operator&quot;: &quot;matchesWildcardPattern&quot;,
  &quot;value&quot;: &quot;PO-????-2026&quot; }

{ &quot;property&quot;: &quot;Title&quot;, &quot;operator&quot;: &quot;doesNotMatchWildcardPattern&quot;,
  &quot;value&quot;: &quot;ID-*&quot; }
</pre></div>


<h3 id="h-4-9-complete-operator-reference" class="wp-block-heading">4.9. Complete operator reference</h3>



<p class="wp-block-paragraph">You reached this point, so it&#8217;s time to have a cheat sheet of all operators. In the below table:</p>



<ul class="wp-block-list">
<li><strong><em>Text</em></strong> and <strong><em>MultiLineText</em></strong> are NOT interchangeable</li>



<li>&#8220;Lookup&#8221; includes both <strong><em>Lookup</em></strong> and <strong><em>MultiSelectLookup</em></strong> (these ARE interchangeable &#8211; one exception for <strong><em>between</em></strong> on MultiSelectLookup because of a bug in M-Files &#8211; the one I mentioned above)</li>



<li>&#8220;Date&#8221; includes <strong><em>Date</em></strong>, <strong><em>Time</em></strong> and <strong><em>Timestamp</em></strong> (these ARE interchangeable &#8211; one exception for <strong><em>notEqual</em></strong> on <strong><em>Timestamp</em></strong> because of a bug in M-Files &#8211; not the same as the one mentioned above)</li>



<li>&#8220;Numeric&#8221; includes <strong><em>Integer</em></strong>, <strong><em>Integer64</em></strong> and <strong><em>Floating</em></strong> (these ARE interchangeable) (&#8220;integer&#8221;/&#8221;real&#8221;)</li>
</ul>



<figure class="wp-block-table"><table><thead><tr><th>Operator</th><th>Value</th><th>Native support for</th><th>Post-filter support for</th><th>Notes</th></tr></thead><tbody><tr><td><strong><em>equals</em></strong></td><td>string</td><td>Text, Lookup, Date, Numeric, Boolean</td><td>MultiLineText</td><td>Exact match</td></tr><tr><td><strong><em>notEqual</em></strong></td><td>string</td><td>Text, Lookup, Date, Numeric, Boolean</td><td>MultiLineText, <strong><em>Timestamp</em></strong></td><td>Excludes exact match. Timestamp is an exception because of a bug in M-Files</td></tr><tr><td><strong><em>lessThan</em></strong></td><td>string</td><td>Text, Lookup, Date, Numeric</td><td>MultiLineText</td><td>Boolean not supported</td></tr><tr><td><strong><em>greaterThan</em></strong></td><td>string</td><td>Text, Lookup, Date, Numeric</td><td>MultiLineText</td><td>Boolean not supported</td></tr><tr><td><strong><em>lessOrEqual</em></strong></td><td>string</td><td>Text, Lookup, Date, Numeric</td><td>MultiLineText</td><td>Boolean not supported</td></tr><tr><td><strong><em>greaterOrEqual</em></strong></td><td>string</td><td>Text, Lookup, Date, Numeric</td><td>MultiLineText</td><td>Boolean not supported</td></tr><tr><td><strong><em>between</em></strong></td><td>array (<strong><em>[&#8220;low&#8221;, &#8220;high&#8221;]</em></strong>)</td><td>Text, Lookup, Date, Numeric</td><td>MultiLineText</td><td>Two-element array, inclusive: <strong><em>low &lt;= value &lt;= high</em></strong>. Boolean not supported</td></tr><tr><td><strong><em>notBetween</em></strong></td><td>array (<strong><em>[&#8220;low&#8221;, &#8220;high&#8221;]</em></strong>)</td><td>&#8211;</td><td>Text, MultiLineText, Lookup, Date, Numeric</td><td>Two-element array, exclusive: <strong><em>value &lt; low OR value &gt; high</em></strong>. Boolean not supported</td></tr><tr><td><strong><em>inList</em></strong></td><td>array (<strong><em>[&#8220;a1&#8221;, &#8220;a2&#8221;, &#8220;a3&#8221;]</em></strong>)</td><td>Lookup</td><td>Text, MultiLineText, Date, Numeric, Boolean</td><td>&#8220;OR&#8221; logic</td></tr><tr><td><strong><em>notInList</em></strong></td><td>array (<strong><em>[&#8220;a1&#8221;, &#8220;a2&#8221;, &#8220;a3&#8221;]</em></strong>)</td><td>Lookup</td><td>Text, MultiLineText, Date, Numeric, Boolean</td><td>Inverse of <strong><em>inList</em></strong></td></tr><tr><td><strong><em>contains</em></strong></td><td>string</td><td>Text, MultiLineText, Lookup</td><td>Date, Numeric, Boolean</td><td>Implicit wildcards on both sides</td></tr><tr><td><strong><em>doesNotContain</em></strong></td><td>string</td><td>Text, MultiLineText, Lookup</td><td>Date, Numeric, Boolean</td><td>Inverse of <strong><em>contains</em></strong></td></tr><tr><td><strong><em>startsWith</em></strong></td><td>string</td><td>Text, Lookup</td><td>MultiLineText, Date, Numeric, Boolean</td><td>Prefix match</td></tr><tr><td><strong><em>doesNotStartWith</em></strong></td><td>string</td><td>Text, Lookup</td><td>MultiLineText, Date, Numeric, Boolean</td><td>Inverse of <strong><em>startsWith</em></strong></td></tr><tr><td><strong><em>endsWith</em></strong></td><td>string</td><td>&#8211;</td><td>All</td><td>Suffix match</td></tr><tr><td><strong><em>doesNotEndWith</em></strong></td><td>string</td><td>&#8211;</td><td>All</td><td>Inverse of <strong><em>endsWith</em></strong></td></tr><tr><td><strong><em>matchesWildcardPattern</em></strong></td><td>string</td><td>Text, Lookup</td><td>MultiLineText, Date, Numeric, Boolean</td><td><em><strong>*</strong> = any chars, <strong><em>?</em></strong> = one char, e.g. <strong><em>PO</em>-??-??-202?</strong></em></td></tr><tr><td><strong><em>doesNotMatchWildcardPattern</em></strong></td><td>string</td><td>Text, Lookup</td><td>MultiLineText, Date, Numeric, Boolean</td><td>Inverse of <strong><em>matchesWildcardPattern</em></strong></td></tr><tr><td><strong><em>isEmpty</em></strong></td><td>&#8211;</td><td>&#8211;</td><td>All</td><td>Property is absent OR (present AND empty)</td></tr><tr><td><strong><em>isNotEmpty</em></strong></td><td>&#8211;</td><td>&#8211;</td><td>All</td><td>Property is present AND non-empty</td></tr><tr><td><strong><em>isPresentEmpty</em></strong></td><td>&#8211;</td><td>All</td><td>&#8211;</td><td>Property is present AND empty</td></tr><tr><td><strong><em>isPresentNotEmpty</em></strong></td><td>&#8211;</td><td>All</td><td>&#8211;</td><td>Property is present AND non-empty</td></tr></tbody></table></figure>



<h3 id="h-4-10-pattern-operators-on-date-properties" class="wp-block-heading">4.10. Pattern operators on date properties</h3>



<p class="wp-block-paragraph">All pattern operators (<strong><em>contains</em></strong>, <strong><em>startsWith</em></strong>, <strong><em>endsWith</em></strong>, <strong><em>matchesWildcardPattern</em></strong> and their negations) work on date properties via the post-filter path, comparing against the ISO <strong><em>yyyy-MM-dd</em></strong> string representation (or <strong><em>yyyy-MM-dd HH:mm</em></strong> for timestamp or <strong><em>HH:mm:ss</em></strong> for time properties). This opens up some convenient patterns, even with <strong><em>&#8220;valueType&#8221;: &#8220;literal&#8221;</em></strong>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;startsWith&quot;,
  &quot;value&quot;: &quot;2026&quot; }

{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;startsWith&quot;,
  &quot;value&quot;: &quot;2026-04&quot; }

{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;endsWith&quot;,
  &quot;value&quot;: &quot;-31&quot; }

{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;matchesWildcardPattern&quot;,
  &quot;value&quot;: &quot;2026-??-??&quot; }
</pre></div>


<p class="wp-block-paragraph">And with <strong><em>&#8220;valueType&#8221;: &#8220;dateToken&#8221;</em></strong>, the token resolves to a full ISO date used as the exact string pattern:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;contains&quot;,
  &quot;value&quot;: &quot;@today&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }

{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;startsWith&quot;,
  &quot;value&quot;: &quot;@startOfMonth+5d&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }
</pre></div>


<p class="wp-block-paragraph">A resolved token produces a full ISO date for the operators, c.f. next section for a deeper dive into dateToken details.</p>



<h2 id="h-5-date-tokens-relative-filters-that-always-make-sense" class="wp-block-heading">5. Date tokens &#8211; relative filters that always make sense</h2>



<p class="wp-block-paragraph">Hardcoding a date like <strong><em>&#8220;2026-01-01&#8221;</em></strong> in a filter works, but it ages badly. The dashboard built today shows different data on January 2nd than it did on December 31st, because the filter is now relative to a different &#8220;today&#8221;.</p>



<p class="wp-block-paragraph">Date tokens solve this. Any string value used with <strong><em>&#8220;valueType&#8221;: &#8220;dateToken&#8221;</em></strong> is resolved to an absolute date at query execution time, so the dashboard stays meaningful as time passes.</p>



<h3 id="h-5-1-anchor-tokens" class="wp-block-heading">5.1. Anchor tokens</h3>



<p class="wp-block-paragraph">The following anchors are recognized:</p>



<figure class="wp-block-table"><table><thead><tr><th>Token</th><th>Resolves to</th></tr></thead><tbody><tr><td><strong><em>@now</em></strong></td><td>Current date AND time</td></tr><tr><td><strong><em>@today</em></strong></td><td>Midnight of the current day</td></tr><tr><td><strong><em>@startOfDay</em></strong></td><td>Same as <strong><em>@today</em></strong></td></tr><tr><td><strong><em>@endOfDay</em></strong></td><td>23:59:59 of the current day</td></tr><tr><td><strong><em>@startOfWeek</em></strong></td><td>Monday of the current ISO week at 00:00:00</td></tr><tr><td><strong><em>@endOfWeek</em></strong></td><td>Sunday of the current ISO week at 23:59:59</td></tr><tr><td><strong><em>@startOfMonth</em></strong></td><td>First day of the current month at 00:00:00</td></tr><tr><td><strong><em>@endOfMonth</em></strong></td><td>Last day of the current month at 23:59:59</td></tr><tr><td><strong><em>@startOfQuarter</em></strong></td><td>First day of the current quarter at 00:00:00</td></tr><tr><td><strong><em>@endOfQuarter</em></strong></td><td>Last day of the current quarter at 23:59:59</td></tr><tr><td><strong><em>@startOfYear</em></strong></td><td>January 1st of the current year at 00:00:00</td></tr><tr><td><strong><em>@endOfYear</em></strong></td><td>December 31st of the current year at 23:59:59</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">So <strong><em>@startOfYear</em></strong>, at the time of writing this blog (i.e. in 2026) is <strong><em>2026-01-01 00:00:00</em></strong>. Starting from January 1st 2027, the same token will automatically resolve to <strong><em>2027-01-01 00:00:00</em></strong> instead. Therefore, the dashboard rolls forward automatically.</p>



<p class="wp-block-paragraph">If there is a need to add more date tokens, it&#8217;s always possible.</p>



<h3 id="h-5-2-offsets-days-hours-minutes-and-seconds" class="wp-block-heading">5.2. Offsets: days, hours, minutes, and seconds</h3>



<p class="wp-block-paragraph">Any anchor presented above can be followed by one or more offsets to add or subtract time:</p>



<figure class="wp-block-table"><table><thead><tr><th>Token</th><th>Meaning</th></tr></thead><tbody><tr><td><strong><em>@today-30d</em></strong></td><td>30 days ago</td></tr><tr><td><strong><em>@today+7d</em></strong></td><td>One week from today</td></tr><tr><td><strong><em>@startOfMonth+14d</em></strong></td><td>14 days into the current month</td></tr><tr><td><strong><em>@endOfYear-7d</em></strong></td><td>One week before year-end</td></tr><tr><td><strong><em>@today+10h</em></strong></td><td>10:00 today</td></tr><tr><td><strong><em>@today+10h+30m</em></strong></td><td>10:30 today</td></tr><tr><td><strong><em>@today+2d+10h+30m</em></strong></td><td>2 days from today at 10:30</td></tr><tr><td><strong><em>@now+2h</em></strong></td><td>Two hours from now</td></tr><tr><td><strong><em>@now-30m</em></strong></td><td>30 minutes ago</td></tr><tr><td><strong><em>@now+45s</em></strong></td><td>45 seconds from now</td></tr><tr><td><strong><em>@now-8h+30m</em></strong></td><td>7 hours and 30 minutes ago</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Each offset uses <strong><em>d</em></strong> for days, <strong><em>h</em></strong> for hours, <strong><em>m</em></strong> for minutes, and <strong><em>s</em></strong> for seconds. As you can see above, offsets can be chained together in any order, so <strong><em>@today+2d+10h+30m</em></strong> is valid, as is <strong><em>@now-8h+30m</em></strong>.</p>



<p class="wp-block-paragraph">The day offset is calendar days, not business days. There is no built-in concept of holidays in the engine as of now.</p>



<h3 id="h-5-3-fixed-iso-dates-with-optional-offset" class="wp-block-heading">5.3. Fixed ISO dates (with optional offset)</h3>



<p class="wp-block-paragraph">A literal ISO date works as both literal as well as a date token. However, if you want to apply an offset, then only dateToken can be used. As previously mentioned, &#8220;literal&#8221; really means a literal strings, so there is no computation done on it.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Effective through&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;,
  &quot;value&quot;: &quot;2026-01-01+90d&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }
</pre></div>


<p class="wp-block-paragraph">This resolves to <strong><em>2026-04-01 00:00:00</em></strong>, at query time. This can be useful when you want a stable absolute anchor but with an offset relative to it.</p>



<h3 id="h-5-3a-when-to-use-now-instead-of-today" class="wp-block-heading">5.3a. When to use @now instead of @today</h3>



<p class="wp-block-paragraph">The key difference between <strong><em>@now</em></strong> and <strong><em>@today</em></strong> is that <strong><em>@now</em></strong> captures the current time including hours, minutes, and seconds, while <strong><em>@today</em></strong> is truncated to midnight.</p>



<p class="wp-block-paragraph">Use <strong><em>@today</em></strong> for day-level filters (most common): &#8220;contracts expiring within 30 days&#8221;, &#8220;documents created this month&#8221;. Use <strong><em>@now</em></strong> when you need intra-day precision: &#8220;events logged in the last 2 hours&#8221;, &#8220;tasks to process in next 4 hours&#8221;. Examples:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
// All activity since this morning at 7am (a fixed time each day)
{ &quot;property&quot;: &quot;Modified&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;,
  &quot;value&quot;: &quot;@today+7h&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }

// Flagged tasks created in the last 8 hours
{ &quot;property&quot;: &quot;Created&quot;, &quot;operator&quot;: &quot;greaterOrEqual&quot;,
  &quot;value&quot;: &quot;@now-8h&quot;, &quot;valueType&quot;: &quot;dateToken&quot; }
</pre></div>


<h2 id="h-6-boolean-filter-values" class="wp-block-heading">6. Boolean filter values</h2>



<p class="wp-block-paragraph">For boolean-typed properties (M-Files &#8220;Boolean (yes/no)&#8221;), the engine accepts both <strong><em>&#8220;Yes&#8221;</em></strong> / <strong><em>&#8220;No&#8221;</em></strong> and <strong><em>&#8220;True&#8221;</em></strong> / <strong><em>&#8220;False&#8221;</em></strong> (case-insensitive):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
{ &quot;property&quot;: &quot;Accepted&quot;, &quot;operator&quot;: &quot;equals&quot;,
  &quot;value&quot;: &quot;Yes&quot; }

{ &quot;property&quot;: &quot;Accepted&quot;, &quot;operator&quot;: &quot;equals&quot;,
  &quot;value&quot;: &quot;True&quot; }
</pre></div>


<p class="wp-block-paragraph"><strong><em>&#8220;Yes&#8221;</em></strong> / <strong><em>&#8220;No&#8221;</em></strong> is the preferred form because that is what M-Files displays in the UI and what users see in their property cards. Worth noting: the M-Files Admin label &#8220;Boolean (yes/no)&#8221; is always English even on a localized vault. So you do not need <strong><em>&#8220;Ja&#8221;</em></strong> / <strong><em>&#8220;Nein&#8221;</em></strong> mappings on a German vault (at least as of today).</p>



<h2 id="h-7-wrap-up" class="wp-block-heading">7. Wrap-up</h2>



<p class="wp-block-paragraph">The query model covers the questions that come up in practice. <strong><em>objectType</em></strong> and <strong><em>class</em></strong> define the scope, <strong><em>filters</em></strong> narrow it with a rich set of operators spanning native server conditions and post-filter cases. Date tokens make filters relative without effort.</p>



<p class="wp-block-paragraph">What is <strong>not</strong> in this post: the <strong><em>aggregation</em></strong> block. That is the topic of <a href="https://www.dbi-services.com/blog/m-files-bd-aggregations-reducers-and-series/" id="45206">Po</a><a href="https://www.dbi-services.com/blog/m-files-bd-aggregations-reducers-and-series/" id="45206" target="_blank" rel="noreferrer noopener">st 6</a>, which covers the aggregation types, the reducers, and the multi-series <strong><em>seriesProperty</em></strong> feature. Once those are explained, every JSON block in the widget posts will make complete sense.</p>



<p class="wp-block-paragraph">Want to know more about this Business Dashboard? <a href="https://www.dbi-services.com/company/contact/" target="_blank" rel="noreferrer noopener">Contact us</a> and we will be happy to showcase it on <a href="https://www.m-files.com/" target="_blank" rel="noreferrer noopener">M-Files</a>.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/">M-Files BD &#8211; Queries: objectType, class, filters, date tokens</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/m-files-bd-queries-objecttype-class-filters-date-tokens/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>A project that looked successful. But…</title>
		<link>https://www.dbi-services.com/blog/a-project-that-looked-successful-but/</link>
					<comments>https://www.dbi-services.com/blog/a-project-that-looked-successful-but/#respond</comments>
		
		<dc:creator><![CDATA[Guillaume Meunier]]></dc:creator>
		<pubDate>Fri, 19 Jun 2026 05:15:56 +0000</pubDate>
				<category><![CDATA[Enterprise content management]]></category>
		<category><![CDATA[digitalization]]></category>
		<category><![CDATA[Enterprise Content Management]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=45142</guid>

					<description><![CDATA[<p>As You know, I will talk about ECM projects again. This time we will focus on what comes after. When everything was delivered on time and within the budget. Yep it&#8217;s not fiction, it happens really 🙂 Every KPI is green! At the last steering committee meeting, congratulations were in order. A slide presentation highlighted [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/a-project-that-looked-successful-but/">A project that looked successful. But…</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">As You know, I will talk about ECM projects again. This time we will focus on what comes after.</p>



<p class="wp-block-paragraph">When everything was delivered on time and within the budget. Yep it&#8217;s not fiction, it happens really <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Every KPI is green!</p>



<p class="wp-block-paragraph">At the last steering committee meeting, congratulations were in order. A slide presentation highlighted the project’s key milestones, its features, and its smooth rollout. Everyone agreed that it was an exemplary project.</p>



<p class="wp-block-paragraph">However, month after month, interest gradually declined and fewer employees used it.</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img loading="lazy" decoding="async" width="300" height="300" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/ellipses-300x300.png" alt="Digital transformation illusion" class="wp-image-45168" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/ellipses-300x300.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/ellipses-150x150.png 150w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/ellipses-768x768.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2026/06/ellipses.png 796w" sizes="auto, (max-width: 300px) 100vw, 300px" /></figure>
</div>


<p class="wp-block-paragraph">There was no official postmortem or formal acknowledgment. It just gradually faded into irrelevance.</p>



<p class="wp-block-paragraph">This is the story of a project that seemed successful but actually wasn’t.</p>



<h2 id="h-why-does-it-look-successful" class="wp-block-heading">Why does it look successful?</h2>



<p class="wp-block-paragraph">At first glance, everything seems perfect:</p>



<ul class="wp-block-list">
<li>Deadlines are respected.</li>



<li>Budget is controlled.</li>



<li>Scope is delivered.</li>



<li>Stakeholders are informed.</li>
</ul>



<p class="wp-block-paragraph">All of the classic project management success criteria were met.</p>



<p class="wp-block-paragraph">However, those metrics measured output, not outcome.</p>



<p class="wp-block-paragraph">No one asked the simple question:</p>



<p class="wp-block-paragraph">Did the project actually solve the intended problem?</p>



<h2 id="h-behind-the-illusion" class="wp-block-heading">Behind the illusion</h2>



<p class="wp-block-paragraph">Under the surface, cracks were real, if you knew where to look.</p>



<p class="wp-block-paragraph">Here are some key points:</p>



<h3 id="h-users" class="wp-block-heading">Users</h3>



<p class="wp-block-paragraph">The training sessions were completed. The documentation was published.</p>



<p class="wp-block-paragraph">But what about adoption? It remains minimal.</p>



<p class="wp-block-paragraph">Employees continued to use spreadsheets, emails, and old tools. Though technically superior, the new system felt like a constraint rather than support.</p>



<p class="wp-block-paragraph">It wasn’t part of their workflow. It was an extra step.</p>



<h3 id="h-requirements" class="wp-block-heading">Requirements</h3>



<p class="wp-block-paragraph">The team implemented everything according to the original specifications.</p>



<p class="wp-block-paragraph">However, no one ever questioned those specifications.</p>



<p class="wp-block-paragraph">Also, the team wrote them too early, based on assumptions and disconnected them from actual user behavior.</p>



<p class="wp-block-paragraph">As a result, the project delivered exactly what stakeholders requested,but not what users needed.</p>



<h3 id="h-success-was-narrowly-defined" class="wp-block-heading">Success was narrowly defined</h3>



<p class="wp-block-paragraph">The project team optimized for:</p>



<ul class="wp-block-list">
<li>Delivery speed</li>



<li>Cost control</li>



<li>Scope completion</li>
</ul>



<p class="wp-block-paragraph">What they didn’t optimize for:</p>



<ul class="wp-block-list">
<li>User adoption</li>



<li>Business impact</li>



<li>Long-term value</li>
</ul>



<p class="wp-block-paragraph">When success is defined narrowly, failure has space to hide.</p>



<h3 id="h-feedback-ignored" class="wp-block-heading">Feedback ignored</h3>



<p class="wp-block-paragraph">During the pilot phase, users raised concerns:</p>



<ul class="wp-block-list">
<li>&#8220;This doesn&#8217;t fit our daily work.&#8221;</li>



<li>&#8220;This adds complexity.&#8221;</li>



<li>&#8220;We don&#8217;t see the benefit.&#8221;</li>
</ul>



<p class="wp-block-paragraph">Rather than viewing these signals as valuable insight, they were labeled as resistance to change.</p>



<p class="wp-block-paragraph">It&#8217;s easier to push forward than to pause and rethink.</p>



<h3 id="h-premature-victory" class="wp-block-heading">Premature victory</h3>



<p class="wp-block-paragraph">Once the project was delivered, attention shifted elsewhere.</p>



<p class="wp-block-paragraph">There was no plan for:</p>



<ul class="wp-block-list">
<li>Adoption tracking</li>



<li>Continuous improvement</li>



<li>Measuring real outcomes</li>
</ul>



<p class="wp-block-paragraph">The project ended when it should have evolved.</p>



<h2 id="h-the-cost-behind-that" class="wp-block-heading">The cost behind that</h2>



<p class="wp-block-paragraph">Because everything appeared successful, the failure went unnoticed.</p>



<p class="wp-block-paragraph">But the cost was real:</p>



<ul class="wp-block-list">
<li>Lost investment</li>



<li>Frustrated users</li>



<li>Erosion of trust in future initiatives</li>



<li>Reinforcement of shadow IT (spreadsheets, workarounds, etc.)</li>
</ul>



<p class="wp-block-paragraph">Even worse, the organization learned the wrong lesson:</p>



<p class="wp-block-paragraph">“We know how to deliver successful projects.”</p>



<h2 id="h-lessons-learned" class="wp-block-heading">Lessons learned</h2>



<p class="wp-block-paragraph">As I&#8217;ve written several times in previous blog posts, ECM failures are rarely due to the solution itself.</p>



<p class="wp-block-paragraph">Rather, they are due to how it was implemented and the lack of improvements after it went live, an ECM is a living system.</p>



<p class="wp-block-paragraph">Here are some point that need to be appreanded differently:</p>



<h3 id="h-redefine-success" class="wp-block-heading">Redefine success</h3>



<p class="wp-block-paragraph">Move beyond the classic triangle of time, cost, and scope.</p>



<p class="wp-block-paragraph">Focus on what brings business value:</p>



<ul class="wp-block-list">
<li>adoption</li>



<li>user satisfaction</li>



<li>simplification and consolidation of processes</li>
</ul>



<p class="wp-block-paragraph">If people don&#8217;t use it, it&#8217;s not successful.</p>



<h3 id="h-be-realistic" class="wp-block-heading">Be realistic</h3>



<p class="wp-block-paragraph">Specifications should not be set in stone.<br>They should evolve based on the following:</p>



<ul class="wp-block-list">
<li>user feedback</li>



<li>iterations</li>



<li>real-world testing</li>
</ul>



<p class="wp-block-paragraph">Projects fail when assumptions take precedence over observation.</p>



<h3 id="h-think-critically" class="wp-block-heading">Think critically</h3>



<p class="wp-block-paragraph">A fully green status report can be misleading.<br>Ask deeper questions:</p>



<p class="wp-block-paragraph">Are users engaged?<br>Are behaviors changing?<br>Is there a measurable impact?</p>



<p class="wp-block-paragraph">If the answers are unclear, the project isn’t finished.</p>



<h3 id="h-go-live-is-the-beginning" class="wp-block-heading">Go-Live is the beginning</h3>



<p class="wp-block-paragraph">Delivery is not the finish line, but rather the starting point.<br>Real success happens after adoption, iteration, and proven value.</p>



<h3 id="h-listen-to-resistance" class="wp-block-heading">Listen to resistance</h3>



<p class="wp-block-paragraph">Resistance is often misinterpreted.</p>



<p class="wp-block-paragraph">It is rarely a matter of resistance to change, but rather a matter of recognizing that every complaint reveals a discrepancy and provides a clue for improvement.</p>



<h2 id="h-finally" class="wp-block-heading">Finally</h2>



<p class="wp-block-paragraph">The most dangerous projects are not the ones that fail visibly. When a project fails, we know why.</p>



<p class="wp-block-paragraph">The real danger lies in projects that succeed&#8230;on paper.</p>



<p class="wp-block-paragraph">Everything looks good because we aren&#8217;t considering what makes sense.</p>



<p class="wp-block-paragraph">It&#8217;s important to keep in mind who we&#8217;re doing those kinds of projects for: the users, and why: to help them with their daily work.</p>



<p class="wp-block-paragraph">Everything else is nonsense.</p>



<p class="wp-block-paragraph">If you’re interested in making your ECM project with <a href="https://www.m-files.com/" target="_blank" rel="noreferrer noopener">M-Files</a> a true success, feel free to contact us at <a href="https://www.dbi-services.com/expertises/digitalization-with-ecm/" target="_blank" rel="noreferrer noopener">dbi services</a>, we’d be happy to help.</p>



<p class="wp-block-paragraph"></p>
<p>L’article <a href="https://www.dbi-services.com/blog/a-project-that-looked-successful-but/">A project that looked successful. But…</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/a-project-that-looked-successful-but/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Lazy Loading (feed)

Served from: www.dbi-services.com @ 2026-07-26 14:40:48 by W3 Total Cache
-->