diff --git a/assets/js/expandable-table.js b/assets/js/expandable-table.js new file mode 100644 index 00000000000..36d82c3b95e --- /dev/null +++ b/assets/js/expandable-table.js @@ -0,0 +1,50 @@ +(function () { + 'use strict'; + + function init() { + document.querySelectorAll('.expandable-table-btn').forEach(function (btn) { + btn.addEventListener('click', function () { + var wrap = btn.closest('.expandable-table-wrap'); + var modal = wrap.nextElementSibling; + openModal(wrap, modal); + }); + }); + } + + function openModal(wrap, modal) { + var title = wrap.dataset.title || ''; + modal.querySelector('.expandable-table-title').textContent = title; + if (title) modal.setAttribute('aria-label', title); + + var body = modal.querySelector('.expandable-table-body'); + body.innerHTML = ''; + body.appendChild(wrap.querySelector('.expandable-table-inner').cloneNode(true)); + + modal.removeAttribute('hidden'); + document.body.classList.add('expandable-table-open'); + + var closeBtn = modal.querySelector('.expandable-table-close'); + closeBtn.focus(); + + function close() { + modal.setAttribute('hidden', ''); + document.body.classList.remove('expandable-table-open'); + btn.focus(); + modal.querySelector('.expandable-table-overlay').removeEventListener('click', close); + document.removeEventListener('keydown', onKey); + } + + var btn = wrap.querySelector('.expandable-table-btn'); + closeBtn.onclick = close; + modal.querySelector('.expandable-table-overlay').addEventListener('click', close); + + function onKey(e) { if (e.key === 'Escape') close(); } + document.addEventListener('keydown', onKey); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})(); diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index 57d4cea4224..c84b1db7570 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -688,4 +688,137 @@ img.ToC-icon{ overflow-y: auto; padding-top: 1.25rem; } -} \ No newline at end of file +} + +// Expandable table modal + +.expandable-table-wrap { + margin-bottom: $spacer; + + .expandable-table-toolbar { + display: flex; + justify-content: flex-start; + margin-bottom: 0.25rem; + } + + .expandable-table-btn { + display: inline-flex; + align-items: center; + gap: 0.35rem; + font-size: 0.75rem; + padding: 0.2rem 0.5rem; + border: 1px solid $gray-border; + color: $link-color; + background: transparent; + border-radius: 4px; + white-space: nowrap; + + &:hover { + background: $gray-100; + border-color: $link-color; + } + + &:focus { + outline: 2px solid $link-color; + outline-offset: 2px; + } + } + + .expandable-table-inner { + overflow-x: auto; + } +} + +body.expandable-table-open { + overflow: hidden; +} + +.expandable-table-modal { + position: fixed; + inset: 0; + z-index: 1060; + display: flex; + align-items: center; + justify-content: center; + + &[hidden] { display: none; } + + .expandable-table-overlay { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.5); + } + + .expandable-table-dialog { + position: relative; + z-index: 1; + width: 90%; + max-width: 1100px; + max-height: 85vh; + background: white; + border-radius: 6px; + box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25); + display: flex; + flex-direction: column; + overflow: hidden; + } + + .expandable-table-header { + padding: 0.75rem 1rem; + border-bottom: 1px solid $gray-border; + background: $gray-100; + display: grid; + grid-template-columns: 1fr minmax(0, auto) 1fr; + align-items: center; + gap: 1rem; + + .expandable-table-title { + grid-column: 2; + grid-row: 1; + text-align: center; + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .expandable-table-close { + grid-column: 1; + grid-row: 1; + justify-self: start; + display: inline-flex; + align-items: center; + gap: 0.4rem; + font-size: 0.875rem; + + &:focus { + outline: 2px solid $link-color; + outline-offset: 2px; + } + } + } + + .expandable-table-body { + overflow: auto; + padding: 1.25rem; + + .expandable-table-inner { + border: none; + border-radius: 0; + overflow: visible; + display: flex; + } + + // Auto margins center small tables in the flex container; shrinking lets wide tables wrap their text to fit the dialog + .expandable-table-inner table { flex: 0 1 auto; width: auto; max-width: 100%; margin: 0 auto !important; } + .expandable-table-inner th, + .expandable-table-inner td { white-space: normal; overflow-wrap: break-word; } + } +} + +@include media-breakpoint-down(md) { + .expandable-table-modal .expandable-table-dialog { + width: 95%; + max-height: 90vh; + } +} diff --git a/content/en/docs/community-tools/contribute-to-mendix-docs/markdown-shortcodes.md b/content/en/docs/community-tools/contribute-to-mendix-docs/markdown-shortcodes.md index 40861d9798f..3bec9a194cc 100644 --- a/content/en/docs/community-tools/contribute-to-mendix-docs/markdown-shortcodes.md +++ b/content/en/docs/community-tools/contribute-to-mendix-docs/markdown-shortcodes.md @@ -108,6 +108,53 @@ public class Hello1 2. Second list item +### Expandable Tables + +Use the `expandable-table` shortcode to add an **Expand Table** button above a wide table. When readers click the button, the table opens in a window on the same page, which makes it easier to read. Place the table between the opening and closing tags, with a blank line after the opening tag and before the closing tag: + +```md +{{% expandable-table title="Attribute Mapping" %}} + +| IdP Attribute | Configured Entity Attribute | +| --- | --- | +| email | Email | +| name | FullName | + +{{% /expandable-table %}} +``` + +The optional `title` parameter sets the title shown at the top of the window. If you omit it or leave it blank, the window has no title. + +Here is an example: + +{{% expandable-table title="Attribute Mapping" %}} + +| IdP Attribute | Configured Entity Attribute | +| --- | --- | +| email | Email | +| name | FullName | + +{{% /expandable-table %}} + +#### Expandable Tables in Lists + +To use the shortcode in a list item, indent the shortcode tags and the table by four spaces, like any other content in the list item, and use the `<` delimiter instead of `%`. The shortcode removes the indentation from the table, so the table does not render as a code block: + +```md +1. Review the mapping: + + {{< expandable-table title="Attribute Mapping" >}} + + | IdP Attribute | Configured Entity Attribute | + | --- | --- | + | email | Email | + | name | FullName | + + {{< /expandable-table >}} + +2. Continue with the next step. +``` + ### Images (Figures) #### Image with Alt Text and Max-Width Class diff --git a/content/en/docs/marketplace/platform-supported-content/modules/SAML/saml-installaion-configuration.md b/content/en/docs/marketplace/platform-supported-content/modules/SAML/saml-installaion-configuration.md index a2ce4b6dbfa..f137e913a4c 100644 --- a/content/en/docs/marketplace/platform-supported-content/modules/SAML/saml-installaion-configuration.md +++ b/content/en/docs/marketplace/platform-supported-content/modules/SAML/saml-installaion-configuration.md @@ -58,6 +58,8 @@ If you use this method, do not forget to set the **SSOLandingPage** constant to The table below introduces you to several key updates when you upgrade the SAML module from V3.x to V4.x. +{{% expandable-table title="Changes in SAML Module Version 4.X" %}} + | Feature | Changes in Version 4.X | | --- | --- | | SSO Configuration | You can perform SSO configuration during design time and deploy time.
For versions below 4.2.0, the module introduced deploy-time configuration and `Custom_Create_IdPConfiguration` microflow for customized SSO configuration.
From version 4.2.0 onwards, you can instead use the `IdPConfiguration_MicroflowName` constant and configure your custom microflow name in it. | @@ -66,6 +68,8 @@ The table below introduces you to several key updates when you upgrade the SAML | InCommon Federation Support | Pre-configured support for InCommon Federation has been removed. You now need to create custom user provisioning microflows in version 4.0.0 | | MxModeleReflection | In the **MxObjects_Overview** page, the MxModeleReflection module refresh is no longer required. It is handled automatically in the **SAML20.Startup**. | +{{% /expandable-table %}} + ## Configuring SAML Module{#config} Configuring the SAML module is crucial for setting up secure authentication within your application. It involves reviewing and updating the Service Provider (SP) settings and creating or updating the Identity Provider (IdP) configuration. @@ -165,6 +169,8 @@ The following entities are used to create IdP configurations: The table below shows you the different attributes and their values for quick reference. You can see the details of these attributes of the above entities in the [Reference Guide for SAML IdP Configuration](/appstore/modules/saml/idp-attributes/) document. +{{% expandable-table title="IdP Configuration Attributes" %}} + | IDPConfiguration(Non-Persistable entity) | Description | Default Value | | --- | --- | --- | | **Alias** (mandatory) | This represents IdPconfiguration Alias | | @@ -203,6 +209,8 @@ The table below shows you the different attributes and their values for quick re | **EncryptionKeyLength** | This constant represents the Encryption length | 2048 bits | | Active | After completion of IdP config it will make the Toggle Active | true | +{{% /expandable-table %}} + Deploy the application and log in with the SSO. For more information, see the [Deploy the Application and Login with SSO](#deploy-application) section above. ### Runtime Configuration Flow{#runtime-config} diff --git a/content/en/docs/marketplace/platform-supported-content/modules/oidc.md b/content/en/docs/marketplace/platform-supported-content/modules/oidc.md index a32f2ccca85..f6b9820586f 100644 --- a/content/en/docs/marketplace/platform-supported-content/modules/oidc.md +++ b/content/en/docs/marketplace/platform-supported-content/modules/oidc.md @@ -201,6 +201,8 @@ If your app is already developed using Mendix 9 or above, but uses the community This section provides an overview of updates for the OIDC SSO module across different versions. It includes new dependencies, snippet replacements, and microflow renaming to ensure a smooth transition while migrating to higher module versions. +{{% expandable-table %}} + | Mendix Version | OIDC SSO Module Version | Important Migration Changes | Additional Information | | --- | --- | --- | --- | | 10.24.0 and above | 4.7.0 | - | A new constant (`EnableAudienceValidation`) has been introduced for API security. Because it is enabled by default, you need to configure the **Resource path** and **Expected audience** value. You can disable audience validation, but Mendix does not recommend this. | @@ -222,6 +224,8 @@ This section provides an overview of updates for the OIDC SSO module across diff | 9.24.2 and above | 3.0.0 (migrating to 3.0.0 and above) | Include [UserCommons](https://marketplace.mendix.com/link/component/223053) module as a dependency. | New UserCommons module | | | | Set `OIDC.Startup` microflow as part of the after-startup microflow. | Assign UserProvisioning for existing IdP configurations. | +{{% /expandable-table %}} + ## Design-time App Configuration{#app-configuration} This section shows you how to configure your app to use OIDC for SSO. @@ -234,11 +238,15 @@ If you are using OIDC module version 3.1.0 and above, you need to configure your Ensure that you have allocated the following user roles to the OIDC module and UserCommons (in version 3.0.0 and above) roles: +{{% expandable-table %}} + | User Role | OIDC Module Role | | --- | --- | | Administrator | OIDC.Administrator, UserCommons.Administrator | | User | OIDC.User | +{{% /expandable-table %}} + {{< figure src="/attachments/appstore/platform-supported-content/modules/oidc/user-roles.png" alt="User roles tab showing Administrator and User roles with their assigned module roles" >}} ### End User Login When Using Single or Multiple IdPs @@ -364,12 +372,16 @@ In this case, the OIDC client is the app you are making. 9. On the **Creating User** tab, select your **User creation microflow**. By default, this module will use standard OpenID claims to provision end-users in your app. Also included is a flow that uses the standard UserInfo endpoint in OIDC, which is useful in the case that your IdP uses opaque tokens. You can set up user provisioning by setting the following standard flows: + {{< expandable-table >}} + | Default Microflow | Use | | --- | --- | | OIDC_CustomUserParsing_Standard
(renamed from UserProvisioning_Standard) | It implements some standard OpenID claims to find/provision a user. | | OIDC_CustomUserParsing_UserInfo
(renamed from UserProvisioning_UserInfo) | It is similar as standard OIDC user parsing flow, except it works with identity providers that use `opaque` tokens. | | OIDC_CustomUserParsing_Salesforce
(renamed from UserProvisioning_Salesforce) | It offers an `id` endpoint that retrieves information about user. You can use OpenID token (`id_token`) to map user attributes. | + {{< /expandable-table >}} + In version below 3.0.0 of the OIDC SSO module, you can configure the timezone and language using the `OIDC_CustomUserParsing_Standard` and `OIDC_CustomUserParsing_UserInfo` microflow. However, in version 3.0.0 and above of the OIDC SSO module, you can set the timezone and language using any standard microflow. You can also use your own custom user entity to manage users of the app. See the section on [User Provisioning Using Your Custom User Entity](#custom_user_entity) for more information on what you can do to implement provisioning logic which fits your business needs. The module includes a Salesforce-specific example. @@ -620,6 +632,8 @@ You can set up custom user provisioning by setting constants when you deploy you You can set up custom user provisioning by setting the following constants. You can set default values when you build your app, but you can override these in the app's environment. +{{% expandable-table %}} + | Constant | Use | Notes | Example | | --- | --- | --- | --- | | `CustomUserEntity` | a custom user entity | in the form `modulename.entityname` – a specialization of `System.User` | `Administration.Account` | @@ -632,6 +646,8 @@ You can set up custom user provisioning by setting the following constants. You | `CustomUserProvisioning` | a custom microflow to use for user provisioning | *optional* – in the form `modulename.microflowname` – the microflow name must begin with the string `UC_CustomProvisioning` | `Mymodule.UC_CustomProvisioning` | | `DisableMxAdmin` | deactivates Mx admin | *optional* | `True` | +{{% /expandable-table %}} + {{% alert color="info" %}} You may have a requirement that users log in to your application only via SSO. However, when you deploy your app on the Mendix Cloud, the platform may still create an MxAdmin user with a local password. From version 2.1.0 of the UserCommons module, if the flag for the `DisableMxAdmin` constant is set to `True`, the MxAdmin user will be deactivated via the startup microflow `ASU_UserCommons_StartUp`. {{% /alert %}} @@ -687,12 +703,16 @@ If the standard configuration meets your needs and your application does not hav In the default configuration, the custom user entity is set as `Administration.Account`, the principal attribute is set as `Name`, and the default attribute mapping is provided. +{{% expandable-table title=" Default Attribute Mapping"%}} + | IdP Attribute | Configured Entity Attribute | | -------------------- | --------------------------- | | email | Email | | name | FullName | | sub | Name | +{{% /expandable-table %}} + ##### Modifying Default Attribute Mapping{#modify-default} You may need a different or custom attribute mapping, for example, if you are configuring OIDC SSO and SCIM together and need a common identifier. For more information, see the [User Identifiers in the OIDC and SCIM Protocols](#user-identifiers-in-the-oidc-and-scim-protocols) section below. @@ -756,12 +776,16 @@ The section below shows the methods to configure user provisioning when using OI By default, the `CUSTOM_UserProvisioning` microflow in the **USE_ME** > **1. Configuration** folder of the OIDC module uses the `OIDC_CustomUserParsing_Standard` microflow. This applies to the following mapping: +{{% expandable-table %}} + | ID-token Provided by your IdP | Attribute of `Administration.Account` Object | | ----------------------------- | ----------------------------- | | sub | Name | | name | Fullname | | email | Email | +{{% /expandable-table %}} + {{% alert color="warning" %}} Do not change the `UserProvisioning_StandardOIDC` microflow. This may cause problems if you upgrade to a newer version of the OIDC SSO module. Apply customizations to the `CUSTOM_UserProvisioning` microflow only. {{% /alert %}} diff --git a/layouts/partials/scripts.html b/layouts/partials/scripts.html index ea4a2b7fbea..903513d9a8a 100644 --- a/layouts/partials/scripts.html +++ b/layouts/partials/scripts.html @@ -62,7 +62,7 @@ {{ $jsAnchor := resources.Get "js/anchor.js" -}} -{{ $jsLodashDebouncd := resources.Get "js/lodash-debounce.js" }} +{{ $jsLodashDebounced := resources.Get "js/lodash-debounce.js" }} {{ $jsLodashThrottle := resources.Get "js/lodash-throttle.js" }} {{ $jsProgressTracking := resources.Get "js/progress-tracking.js" }} @@ -74,8 +74,9 @@ {{ $jsSearch = resources.Get "js/offline-search.js" -}} {{ end -}} - -{{ $jsArray := slice $jsBs $jsBase $jsAnchor $jsLodashDebouncd $jsLodashThrottle $jsProgressTracking $jsSearch $jsPlantuml $jsMarkmap $jsDrawio -}} +{{ $jsExpandableTable := resources.Get "js/expandable-table.js" }} + +{{ $jsArray := slice $jsBs $jsBase $jsAnchor $jsLodashDebounced $jsLodashThrottle $jsProgressTracking $jsExpandableTable $jsSearch $jsPlantuml $jsMarkmap $jsDrawio -}} {{ if .Page.Store.Get "hasmermaid" -}} {{- partial "scripts/mermaid.html" . -}} diff --git a/layouts/shortcodes/expandable-table.html b/layouts/shortcodes/expandable-table.html new file mode 100644 index 00000000000..6b7ac914434 --- /dev/null +++ b/layouts/shortcodes/expandable-table.html @@ -0,0 +1,29 @@ +{{ $_hugo_config := `{ "version": 1 }` }} +
+
+ +
+
+ {{/* Strip leading indentation so tables indented inside a list are not rendered as code blocks */}} + {{ .Inner | replaceRE `(?m)^[ \t]+` "" | markdownify | safeHTML }} +
+
+ +