Create Automatic UI using Custom Secondary Types using Document Management Service

Document Management Service gives the capability of custom UI when a business user has a requirement of showing additional object properties.

For example, the user may want to show a custom metadata from a document which has been created with secondary types in the table columns or there may be requirement to display a list of custom properties for an object in the UI properties section that can be updated later. 

These can be achieved with custom Secondary types. In this blog post, I will show you how to configure these custom types for a particular document or folder, using Document Service repository. 

Preparatory Steps: 

  1. You’ve access to the CMIS workbench. You can download from Apache Chemistry website – https://chemistry.apache.org/java/developing/tools/dev-tools-workbench.html 
  2. You have access to Document Management Service Integration option and have onboarded Document Service Repository. You can refer to my other blog post for creating a DMS instance and onboard a repository. https://blogs.sap.com/2021/04/08/consumption-of-reuse-ui-from-sap-document-management-service-in-sap-fiori-application/ 

Uploading Custom Secondary type into the Document Service repository. 

In this section, you’ll learn how to create and upload secondary types to the repository. 

Follow the steps outlined in this section: 

Step 1:  

  1. Create a JSON schema for uploading Custom secondary type into the repository.
  2. Save the JSON structure as JSON file.
  3. In this JSON schema, we have created a custom secondary type with id – sampleSecondary and it contains one property definition of type Boolean.
{ "id": "sampleSecondary", "localName": "A sample secondary type to show in UI", "localNamespace": null, "displayName": "A sample secondary type to show in UI", "queryName": "sampleSecondary", "description": "A sample secondary type to show in UI", "baseId": "cmis:secondary", "parentId": "cmis:secondary", "creatable": false, "fileable": false, "queryable": true, "fulltextIndexed": false, "includedInSupertypeQuery": false, "controllablePolicy": false, "controllableACL": false, "typeMutability": { "create": true, "update": true, "delete": true }, "propertyDefinitions": { "sampleBooleanPropery": { "id": "sampleBooleanPropery", "localName": "Sample Boolean", "displayName": "Sample Boolean", "queryName": "sampleBooleanPropery", "description": "Sample Boolean", "propertyType": "boolean", "cardinality": "single", "updatability": "readwrite", "inherited": false, "required": false, "queryable": false, "orderable": false, "openChoice": true } } } 

Step 2:  Log in to the cmis workbench. 

Login%20to%20cmis%20workbench

Step 3: Choose the repository under which you want to upload the custom secondary type.

Step 4: Click on Types inside the repository.

Step 5: After you’ve chosen a type, click on CMIS Secondary, then Create Type -> Load Type Definition From JSON. 

Step6: Select the JSON file you just created and upload it to the repository. 

Step7: After you’ve generated the secondary type, look under CMIS Secondary for a new secondary type called sampleSecondary.  

Attaching custom secondary types to cmis objects 

In this section, you’ll learn attaching custom secondary types to cmis objects. 

Step 1:  

  1. Select any object. In this example, we’ve created a document called Questions:docx.
  2. In the cmis workbench, go to the Actions tab.
  3. Click on the Open Property Editor to attach the custom secondary type we have uploaded in earlier steps.

Step 2 : In cmis:SecondaryTypeObjectIds provide the custom property Id that’s used to create the custom Secondary Type. For our use case, it was “cmis:Secondary” and click on the Update button. 

Step 3:  

  1. Once the custom property is updated for the document, select the document Questions.docx and click on Actions tab. 
  2. Select Update Properties now. The new property type “Sample Boolean” will appear in the cmis workbench. 

Step 4: Select true/false as the value and click Update. 

Step 5: After the update is complete, Click the document and select Properties Tab. As you can see, the document’s properties will be updated. 

Adding custom Properties as an additional Column in the Reuse Table and also as apart of the Advanced Search. 

Custom Properties can be modelled in such a way that they can be rendered with Reuse UI based on the business requirements. If the business requirement is to create an additional column for a custom property, proceed as follows. 

 

Step 1:  

Create a property definition in the secondary type you just created. 

The schema is written in the following format. 

"sampleStringProperty": { "maxLength": 4500, "id": "sampleStringProperty", "localName": "Sample String", "displayName": "Sample String", "queryName": "sampleStringProperty", "description": "Sample String", "propertyType": "string", "cardinality": "single", "updatability": "readwrite", "inherited": false, "required": false, "queryable": true, "orderable": false, "openChoice": true, "mcm:miscellaneous": { "positionWeight": "3", "isPartOfTable": "true", "isQueryableInUI": "true" } }

Here we are creating a string propertyType with display Name “Sample String 

The following properties when configured will behave accordingly. 

 

isPartOfTable: This will allow the custom property to be added as a separate column in document Table Reuse UI. 

positionWeight: This will render the column in the exact position Number
 

isQueryableInUI: This property will allow the custom property to be added as a  

part of advanced search in Reuse UI.

When we add this property defined as a part of the Secondary type and attach that secondary type to a document or folder object we should see the UI will be generated accordingly. 

After we add this new property definition to our custom Secondary Type and upload it to the repository, we will see something similar in cmis workbench.  

Step 2 :Now attach the secondary type to a particular object and update the property values. 

Once updated, go to the Properties tab by selecting the document and you should see something like this as shown in the following image. In this example earlier Sample Boolean value that we created earlier is true and the new property that we created, ‘Sample String’ has the value TestString 

Now you can launch the reuse UI (create

The Sample String property, which we just created, appears in a new column. 

Now, when you select the Advanced Search button, the property Sample String will appear, and you may search using this new property Type. 

Custom PropertyTab with Custom Properties. 

Let’s build two more custom properties with the following property definitions to create a Custom Tab in the Properties View. 

"sampleDatetimeProperty": { "resolution": "time", "id": "sampleDatetimeProperty", "localName": "Sample Datetime", "displayName": "Sample Datetime", "queryName": "sampleDatetimeProperty", "description": "Sample Datetime", "propertyType": "datetime", "cardinality": "single", "updatability": "readwrite", "inherited": false, "required": false, "queryable": true, "orderable": true, "openChoice": true, "mcm:miscellaneous": { "positionWeight": "3", "isPartOfTable": "true", "isQueryableInUI": "true" } } 
"sampleSubGroupProperty": { "maxLength": 4500, "id": "sampleSubGroupProperty", "localName": "Sample SubGroup String", "displayName": "Sample SubGroup String", "queryName": "sampleSubGroupProperty", "description": "Sample SubGroup String", "propertyType": "string", "cardinality": "single", "updatability": "readwrite", "inherited": false, "required": false, "queryable": false, "orderable": false, "openChoice": true }

We are creating sampleDateTimeProperty with propertyType dateTime and a sampleSubGroupProperty of type String. 

We also include the dateTime property as a new column in the Reuse Table. 

Now to create Additonal Tabs on the properties View we must add the following json schema in the existing json that we created. 

mcm:propertyGrouping” will contain “mcm:groups” and the Tabs will be created based on these groups. In this current example we are creating two Tabs. To define the display title we will define “mcm:Title” and the value will contain the Tab name i.e. Additional Sample Properties and Additional Second Tab. 

 

If we want to display the earlier custom properties that we created inside these new Tabs we will define the custom ids in “mcm:propertyIds” separated by commas. 

 

If we want to define a grouped header Section inside the Tab we will create subgroups under “mcm:propertySubGrouping” and each subgroup will contain “mcm:Title” and the properties to be grouped inside the subsection under “mcm:PropertyIds” 

"mcm:propertyGrouping": { "mcm:groups": { "sampleProperties": { "mcm:propertyIds": "sampleBooleanPropery,sampleDatetimeProperty,sampleStringProperty", "mcm:title": { "default": "Additional Sample Properties" }, "mcm:propertySubGrouping": { "subgroup1": { "mcm:propertyIds": "sampleSubGroupProperty", "mcm:title": { "default": "Sub Section properties" } } } }, "moreSampleProperties": { "mcm:propertyIds": "sampleBooleanPropery,sampleDatetimeProperty,sampleStringProperty", "mcm:title": { "default": "Additonal Second Tab" }, "mcm:propertySubGrouping": { "subgroup1": { "mcm:propertyIds": "sampleDatetimeProperty", "mcm:title": { "default": "Grouped Property" } } } } } } 

Update the JSON file accordingly to view the changes in the Reuse UI. 

 

The custom properties have been updated with the following values: 

Now open the Reuse UI to see the changes.  

Click on the I button for which the custom properties is attached. You will see two Additional Tabs will be created with the custom Property Types and there will be a subsection with grouped properties for each of the Tabs. 

Complete sample json schema for reference. 

{ "id": "sampleSecondary", "localName": "A sample secondary type to show in UI", "localNamespace": null, "displayName": "A sample secondary type to show in UI", "queryName": "sampleSecondary", "description": "A sample secondary type to show in UI", "baseId": "cmis:secondary", "parentId": "cmis:secondary", "creatable": false, "fileable": false, "queryable": true, "fulltextIndexed": false, "includedInSupertypeQuery": false, "controllablePolicy": false, "controllableACL": false, "typeMutability": { "create": true, "update": true, "delete": true }, "propertyDefinitions": { "sampleBooleanPropery": { "id": "sampleBooleanPropery", "localName": "Sample Boolean", "displayName": "Sample Boolean", "queryName": "sampleBooleanPropery", "description": "Sample Boolean", "propertyType": "boolean", "cardinality": "single", "updatability": "readwrite", "inherited": false, "required": false, "queryable": false, "orderable": false, "openChoice": true }, "sampleStringProperty": { "maxLength": 4500, "id": "sampleStringProperty", "localName": "Sample String", "displayName": "Sample String", "queryName": "sampleStringProperty", "description": "Sample String", "propertyType": "string", "cardinality": "single", "updatability": "readwrite", "inherited": false, "required": false, "queryable": true, "orderable": false, "openChoice": true, "mcm:miscellaneous": { "positionWeight": "3", "isPartOfTable": "true", "isQueryableInUI": "true" } }, "sampleSubGroupProperty": { "maxLength": 4500, "id": "sampleSubGroupProperty", "localName": "Sample SubGroup String", "displayName": "Sample SubGroup String", "queryName": "sampleSubGroupProperty", "description": "Sample SubGroup String", "propertyType": "string", "cardinality": "single", "updatability": "readwrite", "inherited": false, "required": false, "queryable": false, "orderable": false, "openChoice": true }, "sampleDatetimeProperty": { "resolution": "time", "id": "sampleDatetimeProperty", "localName": "Sample Datetime", "displayName": "Sample Datetime", "queryName": "sampleDatetimeProperty", "description": "Sample Datetime", "propertyType": "datetime", "cardinality": "single", "updatability": "readwrite", "inherited": false, "required": false, "queryable": true, "orderable": true, "openChoice": true, "mcm:miscellaneous": { "positionWeight": "3", "isPartOfTable": "true", "isQueryableInUI": "true" } } }, "mcm:propertyGrouping": { "mcm:groups": { "sampleProperties": { "mcm:propertyIds": "sampleBooleanPropery,sampleDatetimeProperty,sampleStringProperty", "mcm:title": { "default": "Additional Sample Properties" }, "mcm:propertySubGrouping": { "subgroup1": { "mcm:propertyIds": "sampleSubGroupProperty", "mcm:title": { "default": "Sub Section properties" } } } }, "moreSampleProperties": { "mcm:propertyIds": "sampleBooleanPropery,sampleDatetimeProperty,sampleStringProperty", "mcm:title": { "default": "Additonal Second Tab" }, "mcm:propertySubGrouping": { "subgroup1": { "mcm:propertyIds": "sampleDatetimeProperty", "mcm:title": { "default": "Grouped Property" } } } } } } } 

Conclusion: Create additional columns, Custom Tabs, and custom properties as part of Advanced Search using json schema modelling, and the UI for the same will be generated automatically.

Please feel free to leave a comment on this blog post with your comments, and I would greatly appreciate it. 

You can also post a question under the tag SAP Document Management Service, and we’ll be pleased to respond to all of your inquiries and incorporate your suggestions. 

 

Stay tuned for the next blog post.