209: TDM - Show the resources through a ListView widget

Task-Url: https://support.d4science.org/issues/209

Updated ResourcesListView

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/tabular-data-resources-widget@115201 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Giancarlo Panichi 2015-06-03 16:58:06 +00:00
parent 2e6ac8d835
commit 281a27e875
8 changed files with 265 additions and 67 deletions

View File

@ -1,4 +1,4 @@
<div class="{style.thumb}"> <div class="{style.thumb}">
<!-- <img src="{resourceTDDescriptor.pathUri}" title="{resourceTDDescriptor.name}">--> <img src="{thumbnailPath}">
</div> </div>
<span class="x-editable">{resourceTDDescriptor.name:shorten(18)}</span> <span class="x-editable">{resourceTDDescriptor.name:shorten(18)}</span>

View File

@ -0,0 +1,26 @@
@CHARSET "UTF-8";
.details {
padding: 10px;
text-align: center;
}
.detailsInfo {
border-top: 1px solid #ccc;
font: 11px Arial, Helvetica, sans-serif;
margin-top: 5px;
padding-top: 5px;
text-align: left;
}
.detailsTable {
border: none;
}
.detailsHead {
font-weight: bold;
}
.detailsData {
padding-left: 5px;
}

View File

@ -1,8 +1,13 @@
<div class="details"> <div class="{style.details}">
<!-- <img src="{thumbnailPath}" title="{resourceTDDescriptor.name}">
<img src="{pathUri}">--> <div class="{style.detailsInfo}">
<div class="details-info"> <table class="{style.detailsTable}">
<b>Name:</b> <span>{resourceTDDescriptor.name}</span><b>Description:</b> <tr><td class="{style.detailsHead}">Name:</td></tr>
<span>{resourceTDDescriptor.description}</span><b>Creation Date:</b> <span>{resourceTDDescriptor.creationDate}</span> <tr><td class="{style.detailsData}">{resourceTDDescriptor.name}</td></tr>
<tr><td class="{style.detailsHead}">Description:</td></tr>
<tr><td class="{style.detailsData}">{resourceTDDescriptor.description}</td></tr>
<tr><td class="{style.detailsHead}">Creation Date:</td></tr>
<tr><td class="{style.detailsData}">{resourceTDDescriptor.creationDate}</td></tr>
</table>
</div> </div>
</div> </div>

View File

@ -1,13 +1,19 @@
package org.gcube.portlets.user.td.resourceswidget.client; package org.gcube.portlets.user.td.resourceswidget.client;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import org.gcube.portlets.user.td.gwtservice.client.rpc.TDGWTServiceAsync; import org.gcube.portlets.user.td.gwtservice.client.rpc.TDGWTServiceAsync;
import org.gcube.portlets.user.td.gwtservice.shared.exception.TDGWTIsLockedException; import org.gcube.portlets.user.td.gwtservice.shared.exception.TDGWTIsLockedException;
import org.gcube.portlets.user.td.gwtservice.shared.exception.TDGWTSessionExpiredException; import org.gcube.portlets.user.td.gwtservice.shared.exception.TDGWTSessionExpiredException;
import org.gcube.portlets.user.td.gwtservice.shared.tr.resources.InternalURITD;
import org.gcube.portlets.user.td.gwtservice.shared.tr.resources.ResourceTD;
import org.gcube.portlets.user.td.gwtservice.shared.tr.resources.ResourceTDDescriptor; import org.gcube.portlets.user.td.gwtservice.shared.tr.resources.ResourceTDDescriptor;
import org.gcube.portlets.user.td.gwtservice.shared.tr.resources.StringResourceTD;
import org.gcube.portlets.user.td.gwtservice.shared.tr.resources.TableResourceTD;
import org.gcube.portlets.user.td.resourceswidget.client.resources.ResourceBundle;
import org.gcube.portlets.user.td.resourceswidget.client.utils.UtilsGXT3; import org.gcube.portlets.user.td.resourceswidget.client.utils.UtilsGXT3;
import org.gcube.portlets.user.td.widgetcommonevent.client.event.SessionExpiredEvent; import org.gcube.portlets.user.td.widgetcommonevent.client.event.SessionExpiredEvent;
import org.gcube.portlets.user.td.widgetcommonevent.client.type.SessionExpiredType; import org.gcube.portlets.user.td.widgetcommonevent.client.type.SessionExpiredType;
@ -17,15 +23,20 @@ import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.resources.client.ClientBundle; import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource; import com.google.gwt.resources.client.CssResource;
import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeUri;
import com.google.gwt.safehtml.shared.UriUtils;
import com.google.gwt.text.shared.AbstractSafeHtmlRenderer; import com.google.gwt.text.shared.AbstractSafeHtmlRenderer;
import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HTML;
import com.google.web.bindery.event.shared.EventBus; import com.google.web.bindery.event.shared.EventBus;
import com.sencha.gxt.cell.core.client.SimpleSafeHtmlCell; import com.sencha.gxt.cell.core.client.SimpleSafeHtmlCell;
import com.sencha.gxt.cell.core.client.form.ComboBoxCell.TriggerAction;
import com.sencha.gxt.core.client.IdentityValueProvider; import com.sencha.gxt.core.client.IdentityValueProvider;
import com.sencha.gxt.core.client.Style.SelectionMode; import com.sencha.gxt.core.client.Style.SelectionMode;
import com.sencha.gxt.core.client.XTemplates; import com.sencha.gxt.core.client.XTemplates;
@ -34,26 +45,30 @@ import com.sencha.gxt.core.client.XTemplates.FormatterFactories;
import com.sencha.gxt.core.client.XTemplates.FormatterFactory; import com.sencha.gxt.core.client.XTemplates.FormatterFactory;
import com.sencha.gxt.core.client.dom.ScrollSupport.ScrollMode; import com.sencha.gxt.core.client.dom.ScrollSupport.ScrollMode;
import com.sencha.gxt.core.client.resources.CommonStyles; import com.sencha.gxt.core.client.resources.CommonStyles;
import com.sencha.gxt.core.client.resources.ThemeStyles;
import com.sencha.gxt.core.client.util.Format; import com.sencha.gxt.core.client.util.Format;
import com.sencha.gxt.core.client.util.Margins;
import com.sencha.gxt.data.client.loader.RpcProxy; import com.sencha.gxt.data.client.loader.RpcProxy;
import com.sencha.gxt.data.shared.ListStore; import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.ModelKeyProvider; import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.SortDir; import com.sencha.gxt.data.shared.SortDir;
import com.sencha.gxt.data.shared.Store; import com.sencha.gxt.data.shared.Store;
import com.sencha.gxt.data.shared.Store.StoreSortInfo; import com.sencha.gxt.data.shared.Store.StoreSortInfo;
import com.sencha.gxt.data.shared.StringLabelProvider;
import com.sencha.gxt.data.shared.loader.ListLoadConfig; import com.sencha.gxt.data.shared.loader.ListLoadConfig;
import com.sencha.gxt.data.shared.loader.ListLoadResult; import com.sencha.gxt.data.shared.loader.ListLoadResult;
import com.sencha.gxt.data.shared.loader.ListLoader; import com.sencha.gxt.data.shared.loader.ListLoader;
import com.sencha.gxt.data.shared.loader.ListStoreBinding; import com.sencha.gxt.data.shared.loader.ListStoreBinding;
import com.sencha.gxt.data.shared.loader.Loader; import com.sencha.gxt.data.shared.loader.Loader;
import com.sencha.gxt.theme.base.client.listview.ListViewCustomAppearance; import com.sencha.gxt.theme.base.client.listview.ListViewCustomAppearance;
import com.sencha.gxt.widget.core.client.Dialog;
import com.sencha.gxt.widget.core.client.Dialog.PredefinedButton;
import com.sencha.gxt.widget.core.client.FramedPanel; import com.sencha.gxt.widget.core.client.FramedPanel;
import com.sencha.gxt.widget.core.client.ListView; import com.sencha.gxt.widget.core.client.ListView;
import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer;
import com.sencha.gxt.widget.core.client.container.BorderLayoutContainer.BorderLayoutData;
import com.sencha.gxt.widget.core.client.container.MarginData; import com.sencha.gxt.widget.core.client.container.MarginData;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer; import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData; import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData;
import com.sencha.gxt.widget.core.client.form.SimpleComboBox;
import com.sencha.gxt.widget.core.client.form.StoreFilterField; import com.sencha.gxt.widget.core.client.form.StoreFilterField;
import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent; import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent;
import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent.SelectionChangedHandler; import com.sencha.gxt.widget.core.client.selection.SelectionChangedEvent.SelectionChangedHandler;
@ -74,14 +89,23 @@ public class ResourcesListViewPanel extends FramedPanel {
public interface DetailRenderer extends XTemplates { public interface DetailRenderer extends XTemplates {
@XTemplate(source = "ResourcesListViewDetail.html") @XTemplate(source = "ResourcesListViewDetail.html")
public SafeHtml render(ResourceTDDescriptor resourceTDDescriptor); public SafeHtml render(ResourceTDDescriptor resourceTDDescriptor,
SafeUri thumbnailPath, ResourceListViewDetailCSS style);
}
public interface DetailRendererBundle extends ClientBundle {
public static final DetailRendererBundle INSTANCE = GWT
.create(DetailRendererBundle.class);
@Source("ResourcesListViewDetail.css")
ResourceListViewDetailCSS css();
} }
@FormatterFactories(@FormatterFactory(factory = ShortenFactory.class, name = "shorten")) @FormatterFactories(@FormatterFactory(factory = ShortenFactory.class, name = "shorten"))
public interface Renderer extends XTemplates { public interface Renderer extends XTemplates {
@XTemplate(source = "ResourcesListView.html") @XTemplate(source = "ResourcesListView.html")
public SafeHtml renderItem(ResourceTDDescriptor resourceTDDescriptor, public SafeHtml renderItem(ResourceTDDescriptor resourceTDDescriptor,
ResourceListViewCSS style); SafeUri thumbnailPath, ResourceListViewCSS style);
} }
public interface ResourcesListViewBundle extends ClientBundle { public interface ResourcesListViewBundle extends ClientBundle {
@ -92,6 +116,19 @@ public class ResourcesListViewPanel extends FramedPanel {
ResourceListViewCSS css(); ResourceListViewCSS css();
} }
public interface ResourceListViewDetailCSS extends CssResource {
String details();
String detailsInfo();
String detailsTable();
String detailsHead();
String detailsData();
}
public interface ResourceListViewCSS extends CssResource { public interface ResourceListViewCSS extends CssResource {
String over(); String over();
@ -100,6 +137,7 @@ public class ResourcesListViewPanel extends FramedPanel {
String thumb(); String thumb();
String thumbWrap(); String thumbWrap();
} }
static class Shorten implements Formatter<String> { static class Shorten implements Formatter<String> {
@ -121,9 +159,48 @@ public class ResourcesListViewPanel extends FramedPanel {
} }
} }
private Dialog chooser; enum ResourcesSortInfo {
Name("Name"), CreationDate("Creation Date");
private String id;
private static List<String> resourcesSortInfoStringList;
static {
resourcesSortInfoStringList = new ArrayList<String>();
for (ResourcesSortInfo r : values()) {
resourcesSortInfoStringList.add(r.getId());
}
}
private ResourcesSortInfo(String id) {
this.id = id;
}
public String getId() {
return id;
}
public String toString() {
return id;
}
public static List<ResourcesSortInfo> asList() {
List<ResourcesSortInfo> list = Arrays.asList(values());
return list;
}
public static List<String> asStringList() {
return resourcesSortInfoStringList;
}
}
// private Dialog chooser;
private HTML details; private HTML details;
private static DetailRenderer detailRenderer; private static DetailRenderer detailRenderer;
private static ResourceListViewDetailCSS detailStyle;
private TRId trId; private TRId trId;
private EventBus eventBus; private EventBus eventBus;
@ -134,6 +211,7 @@ public class ResourcesListViewPanel extends FramedPanel {
private boolean drawed = false; private boolean drawed = false;
private ListView<ResourceTDDescriptor, ResourceTDDescriptor> view; private ListView<ResourceTDDescriptor, ResourceTDDescriptor> view;
private SimpleComboBox<String> comboSort;
public ResourcesListViewPanel(TRId trId, EventBus eventBus) { public ResourcesListViewPanel(TRId trId, EventBus eventBus) {
super(); super();
@ -166,6 +244,9 @@ public class ResourcesListViewPanel extends FramedPanel {
protected void create() { protected void create() {
Log.debug("Create Resource List View"); Log.debug("Create Resource List View");
DetailRendererBundle.INSTANCE.css().ensureInjected();
detailStyle = DetailRendererBundle.INSTANCE.css();
detailRenderer = GWT.create(DetailRenderer.class); detailRenderer = GWT.create(DetailRenderer.class);
RpcProxy<Object, List<ResourceTDDescriptor>> proxy = new RpcProxy<Object, List<ResourceTDDescriptor>>() { RpcProxy<Object, List<ResourceTDDescriptor>> proxy = new RpcProxy<Object, List<ResourceTDDescriptor>>() {
@ -189,14 +270,17 @@ public class ResourcesListViewPanel extends FramedPanel {
@Override @Override
public int compare(ResourceTDDescriptor o1, public int compare(ResourceTDDescriptor o1,
ResourceTDDescriptor o2) { ResourceTDDescriptor o2) {
/*
* String v = comboSort.getCurrentValue(); if String v = comboSort.getCurrentValue();
* (v.equals("Name")) { return if (v.equals("Name")) {
* o1.getName().compareToIgnoreCase(o2.getName()); } return o1.getName().compareToIgnoreCase(
* else if (v.equals("File Size")) { return o1.getSize() o2.getName());
* < o2.getSize() ? -1 : 1; } else { } else if (v.equals("Creation Date")) {
* o1.getDate().compareTo(o2.getDate()); } return o1.getCreationDate().compareTo(
*/ o2.getCreationDate());
}
return 0; return 0;
} }
}, SortDir.ASC)); }, SortDir.ASC));
@ -234,19 +318,24 @@ public class ResourcesListViewPanel extends FramedPanel {
toolbar.add(filterField); toolbar.add(filterField);
toolbar.add(new SeparatorToolItem()); toolbar.add(new SeparatorToolItem());
toolbar.add(new LabelToolItem("Sort By:")); toolbar.add(new LabelToolItem("Sort By:"));
/*
* comboSort = new SimpleComboBox<String>(new comboSort = new SimpleComboBox<String>(
* StringLabelProvider<String>()); new StringLabelProvider<String>());
* comboSort.setTriggerAction(TriggerAction.ALL); comboSort.setTriggerAction(TriggerAction.ALL);
* comboSort.setEditable(false); comboSort.setForceSelection(true); comboSort.setEditable(false);
* comboSort.setWidth(120); comboSort.add("Name"); comboSort.setForceSelection(true);
* comboSort.add("File Size"); comboSort.add("Last Modified"); comboSort.setWidth(120);
* comboSort.setValue("Name"); comboSort.addSelectionHandler(new comboSort.add(ResourcesSortInfo.asStringList());
* SelectionHandler<String>() { comboSort.setValue(ResourcesSortInfo.CreationDate.getId());
* comboSort.addSelectionHandler(new SelectionHandler<String>() {
* @Override public void onSelection(SelectionEvent<String> event) {
* store.applySort(false); } }); toolbar.add(comboSort); @Override
*/ public void onSelection(SelectionEvent<String> event) {
store.applySort(false);
}
});
toolbar.add(comboSort);
// //
ResourcesListViewBundle.INSTANCE.css().ensureInjected(); ResourcesListViewBundle.INSTANCE.css().ensureInjected();
@ -300,8 +389,33 @@ public class ResourcesListViewPanel extends FramedPanel {
view.setCell(new SimpleSafeHtmlCell<ResourceTDDescriptor>( view.setCell(new SimpleSafeHtmlCell<ResourceTDDescriptor>(
new AbstractSafeHtmlRenderer<ResourceTDDescriptor>() { new AbstractSafeHtmlRenderer<ResourceTDDescriptor>() {
@Override @Override
public SafeHtml render(ResourceTDDescriptor object) { public SafeHtml render(ResourceTDDescriptor descriptor) {
return renderer.renderItem(object, style); SafeUri thumbnailPath = ResourceBundle.INSTANCE
.resources32().getSafeUri();
ResourceTD resourceTD = descriptor.getResourceTD();
if (resourceTD instanceof InternalURITD) {
InternalURITD internalURITD = (InternalURITD) resourceTD;
if (internalURITD.getThumbnailTD() != null
&& internalURITD.getThumbnailTD().getUrl() != null) {
thumbnailPath = UriUtils
.fromTrustedString(internalURITD
.getThumbnailTD().getUrl());
}
} else {
if (resourceTD instanceof StringResourceTD) {
thumbnailPath = ResourceBundle.INSTANCE
.resources32().getSafeUri();
} else {
if (resourceTD instanceof TableResourceTD) {
thumbnailPath = ResourceBundle.INSTANCE
.resources32().getSafeUri();
}
}
}
return renderer.renderItem(descriptor, thumbnailPath,
style);
} }
})); }));
view.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); view.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
@ -317,38 +431,60 @@ public class ResourcesListViewPanel extends FramedPanel {
VerticalLayoutContainer main = new VerticalLayoutContainer(); VerticalLayoutContainer main = new VerticalLayoutContainer();
main.setScrollMode(ScrollMode.AUTO); main.setScrollMode(ScrollMode.AUTO);
main.setAdjustForScroll(true); // main.setAdjustForScroll(true);
main.setBorders(true); main.setBorders(true);
main.add(toolbar, new VerticalLayoutData(1, -1)); main.add(toolbar, new VerticalLayoutData(1, -1));
main.add(view, new VerticalLayoutData(1, 1)); main.add(view, new VerticalLayoutData(1, 1));
/* details = new HTML();
* details = new HTML(); details.addStyleName(ThemeStyles.get().style().border());
* details.addStyleName(ThemeStyles.get().style().border()); details.getElement().getStyle().setBackgroundColor("white");
* details.getElement().getStyle().setBackgroundColor("white");
*
* BorderLayoutData eastData = new BorderLayoutData(200);
* eastData.setSplit(true);
*
* BorderLayoutData centerData = new BorderLayoutData();
* centerData.setMargins(new Margins(0, 5, 0, 0));
*
* BorderLayoutContainer con = new BorderLayoutContainer();
* con.setCenterWidget(main, centerData); con.setEastWidget(details,
* eastData);
*/
add(main, new MarginData(0)); BorderLayoutData eastData = new BorderLayoutData(200);
eastData.setSplit(true);
BorderLayoutData centerData = new BorderLayoutData();
centerData.setMargins(new Margins(0, 5, 0, 0));
BorderLayoutContainer con = new BorderLayoutContainer();
con.setCenterWidget(main, centerData);
con.setEastWidget(details, eastData);
add(con, new MarginData(0));
} }
private void onSelectionChange( private void onSelectionChange(
SelectionChangedEvent<ResourceTDDescriptor> se) { SelectionChangedEvent<ResourceTDDescriptor> se) {
if (se.getSelection().size() > 0) { if (se.getSelection().size() > 0) {
details.setHTML(detailRenderer.render(se.getSelection().get(0)) ResourceTDDescriptor descriptor = se.getSelection().get(0);
.asString()); SafeUri thumbnailPath = ResourceBundle.INSTANCE.resources32()
chooser.getButton(PredefinedButton.OK).enable(); .getSafeUri();
ResourceTD resourceTD = descriptor.getResourceTD();
if (resourceTD instanceof InternalURITD) {
InternalURITD internalURITD = (InternalURITD) resourceTD;
if (internalURITD.getThumbnailTD() != null
&& internalURITD.getThumbnailTD().getUrl() != null) {
thumbnailPath = UriUtils.fromTrustedString(internalURITD
.getThumbnailTD().getUrl());
}
} else { } else {
chooser.getButton(PredefinedButton.OK).disable(); if (resourceTD instanceof StringResourceTD) {
thumbnailPath = ResourceBundle.INSTANCE.resources32()
.getSafeUri();
} else {
if (resourceTD instanceof TableResourceTD) {
thumbnailPath = ResourceBundle.INSTANCE.resources32()
.getSafeUri();
}
}
}
details.setHTML(detailRenderer.render(descriptor, thumbnailPath,
detailStyle).asString());
// chooser.getButton(PredefinedButton.OK).enable();
} else {
// chooser.getButton(PredefinedButton.OK).disable();
details.setHTML(""); details.setHTML("");
} }
} }
@ -372,7 +508,7 @@ public class ResourcesListViewPanel extends FramedPanel {
Log.error("Error Retrieving Resources: " Log.error("Error Retrieving Resources: "
+ caught.getLocalizedMessage()); + caught.getLocalizedMessage());
UtilsGXT3.alert("Error retrieving resources", UtilsGXT3.alert("Error retrieving resources",
"Error retrieving resources"); caught.getLocalizedMessage());
} }
} }
callback.onFailure(caught); callback.onFailure(caught);

View File

@ -817,7 +817,7 @@ public class ResourcesPanel extends FramedPanel {
Log.error("Error Retrieving Resources: " Log.error("Error Retrieving Resources: "
+ caught.getLocalizedMessage()); + caught.getLocalizedMessage());
UtilsGXT3.alert("Error retrieving resources", UtilsGXT3.alert("Error retrieving resources",
"Error retrieving resources"); caught.getLocalizedMessage());
} }
} }
callback.onFailure(caught); callback.onFailure(caught);

View File

@ -1,4 +1,4 @@
<div class="{style.thumb}"> <div class="{style.thumb}">
<!-- <img src="{resourceTDDescriptor.pathUri}" title="{resourceTDDescriptor.name}">--> <img src="{thumbnailPath}">
</div> </div>
<span class="x-editable">{resourceTDDescriptor.name:shorten(18)}</span> <span class="x-editable">{resourceTDDescriptor.name:shorten(18)}</span>

View File

@ -0,0 +1,26 @@
@CHARSET "UTF-8";
.details {
padding: 10px;
text-align: center;
}
.detailsInfo {
border-top: 1px solid #ccc;
font: 11px Arial, Helvetica, sans-serif;
margin-top: 5px;
padding-top: 5px;
text-align: left;
}
.detailsTable {
border: none;
}
.detailsHead {
font-weight: bold;
}
.detailsData {
padding-left: 5px;
}

View File

@ -1,8 +1,13 @@
<div class="details"> <div class="{style.details}">
<!-- <img src="{thumbnailPath}" title="{resourceTDDescriptor.name}">
<img src="{pathUri}">--> <div class="{style.detailsInfo}">
<div class="details-info"> <table class="{style.detailsTable}">
<b>Name:</b> <span>{resourceTDDescriptor.name}</span><b>Description:</b> <tr><td class="{style.detailsHead}">Name:</td></tr>
<span>{resourceTDDescriptor.description}</span><b>Creation Date:</b> <span>{resourceTDDescriptor.creationDate}</span> <tr><td class="{style.detailsData}">{resourceTDDescriptor.name}</td></tr>
<tr><td class="{style.detailsHead}">Description:</td></tr>
<tr><td class="{style.detailsData}">{resourceTDDescriptor.description}</td></tr>
<tr><td class="{style.detailsHead}">Creation Date:</td></tr>
<tr><td class="{style.detailsData}">{resourceTDDescriptor.creationDate}</td></tr>
</table>
</div> </div>
</div> </div>