Migrating details- and info-like columned list views to a details view

There are details- and info-like views that rely on a columned list phlow view to display a table with some interesting object details. For example: Date>>#gtDetailsFor: gtDetailsFor: aView <gtView> ^ aView columnedList title: 'Details'; items: [ {('iso' -> self yyyymmdd). ('year' -> self year). ('month' -> self monthIndex). ('month name' -> self monthName). ('day of month' -> self dayOfMonth). ('day of week' -> self dayOfWeekName). ('day of year' -> self dayOfYear)} ]; column: 'Key' text: #key; column: 'Value' text: #value; send: #value or GtLClassChangeDataExtractor>>#gtDetailsFor: gtDetailsFor: aView <gtView> ^ aView columnedList title: 'Details'; priority: 10; items: [ {'Request' -> request. 'Target class' -> targetClass. 'Superclass' -> superclass. 'Instance slots' -> instanceVariables. 'Class slots' -> classInstanceVariables. 'Class variables' -> classVariables. 'Package name' -> packageName. 'Package tag name' -> packageTagName} ]; column: 'Property' text: #key; column: 'Value' text: #value; send: #value . Notice the structure: such views use an ordered dictionary or a collection of associations and then declare two columns for a property name and its value. Some of them even format the textual representation of the value as part of the items: block. The downside is that the implemnetation of such views is verbose. To simplify creation of details views we introduced a dedicated GtPhlowDetailsView GtPhlowViewDecorator << #GtPhlowDetailsView slots: { #rows }; tag: '! Views'; package: 'GToolkit-Phlow' , which has a very small api and doesn't require send:. The Date>>#gtDetailsFor: gtDetailsFor: aView <gtView> ^ aView columnedList title: 'Details'; items: [ {('iso' -> self yyyymmdd). ('year' -> self year). ('month' -> self monthIndex). ('month name' -> self monthName). ('day of month' -> self dayOfMonth). ('day of week' -> self dayOfWeekName). ('day of year' -> self dayOfYear)} ]; column: 'Key' text: #key; column: 'Value' text: #value; send: #value can be rewritten like this using a new details view:

        
Date >> gtDetailsFor: aView
	<gtView>
	^ aView details
		title: 'Details';
		row: 'iso' value: [ self yyyymmdd ];
		row: 'year' value: [ self year ];
		row: 'month' value: [ self monthIndex ];
		row: 'month name' value: [ self monthName ];
		row: 'day of month' value: [ self dayOfMonth ];
		row: 'day of week' value: [ self dayOfWeekName ];
		row: 'day of year' value: [ self dayOfYear ]
        
      

        
gtDetailsFor: aView
	<gtView>
	^ aView columnedList
		title: 'Details';
		priority: 10;
		items: [
			{ 'Request' -> request.
			  'Target class name' -> targetClassName.
			  'Superclass' -> superclass.
			  'Instance slots' -> instanceSlots.
			  'Class slots' -> classSlots. } ];
		column: 'Property' text: #key;
		column: 'Value' text: #value;
		send: #value
        
      

becomes

        
gtDetailsFor: aView
	<gtView>
	^ aView details
		title: 'Details';
		priority: 10;
		row: 'Request' value: [ request ];
		row: 'Target class name' value: [ targetClassName ];
		row: 'Superclass' value: [ superclass ];
		row: 'Instance slots' value: [ instanceSlots ];
		row: 'Class slots' value: [ classSlots ]
        
      

        
gtDetailsFor: aView
	<gtView>
	^ aView columnedList
		title: 'Details';
		priority: 10;
		items: [
			{ 'Name' -> name asString capitalized.
			  'City' -> cityName asLowercase } ];
		column: 'Property' text: #key;
		column: 'Value' text: #value;
		send: #value
        
      

becomes

        
gtDetailsFor: aView
	<gtView>
	^ aView columnedList
		title: 'Details';
		priority: 10;
		row: 'Name' value: [ name ] text: [ :each | each asString capitalized ];
		row: 'City' value: [ self city ] text: [ :each | each name asLowercase ]