UNPKG

graphdb-workbench

Version:
489 lines (455 loc) 30 kB
<link href="css/graphs-vizualizations.css?v=3.1.0-RC3" rel="stylesheet"/> <link href="css/rdf-details-side-panel.css?v=3.1.0-RC3" rel="stylesheet"/> <link href="css/lib/ng-tags-input/ng-tags-input.min.css?v=3.1.0-RC3" rel="stylesheet"/> <link href="js/lib/d3-tip/d3-tip.css?v=3.1.0-RC3" rel="stylesheet"/> <div class="container-fluid visual-graph-view"> <h1> {{title}} <page-info-tooltip></page-info-tooltip> </h1> <div core-errors license></div> <div system-repo-warning></div> <div class="alert alert-danger" ng-show="repositoryError"> <p>{{'not.usable.active.repo.error' | translate}}</p> <p>{{repositoryError}}</p> </div> <div class="toolbar-holder" ng-show="configLoaded && isLicenseValid() && getActiveRepository() && 'SYSTEM' !== getActiveRepository()"> <button ng-show="!queryResultsMode && !noGoHome" class="btn btn-link p-0 return-home-btn" gdb-tooltip="{{'visual.graph.home.label' | translate}}" tooltip-placement="bottom" ng-click="goToHome()"> <em class="icon-arrow-up icon-2x"></em> </button> <button ng-show="!queryResultsMode && configLoaded.startMode == 'search'" class="btn btn-link p-0" gdb-tooltip="{{'search.another.resource.label' | translate}}" tooltip-placement="bottom" ng-disabled="!nodeSelected" ng-click="searchVisible = !searchVisible"> <em class="icon-search icon-2x"></em> </button> <button class="btn btn-link p-0" gdb-tooltip="{{'visual.graph.rotate.graph.left' | translate}}" tooltip-placement="bottom" ng-disabled="!nodeSelected" ng-click="rotate(true)"> <em class="icon-rotate-left icon-2x"></em> </button> <button class="btn btn-link p-0" gdb-tooltip="{{'visual.graph.rotate.graph.right' | translate}}" tooltip-placement="bottom" ng-disabled="!nodeSelected" ng-click="rotate(false)"> <em class="icon-rotate-right icon-2x"></em> </button> <button class="btn btn-link p-0" gdb-tooltip="{{numberOfPinnedNodes > 0 ? 'visual.graph.unpin.nodes' : 'visual.graph.pin.down.nodes' | translate}}" ng-class="numberOfPinnedNodes > 0 ? 'active' : ''" tooltip-placement="bottom" ng-disabled="!nodeSelected" ng-click="togglePinAllNodes()"> <em class="icon-pin icon-2x"></em> </button> <button class="btn btn-link p-0" gdb-tooltip="{{'visual.save.graph.snapshot' | translate}}" tooltip-placement="bottom" ng-if="isUser() && !embedded" ng-disabled="!nodeSelected" ng-click="saveOrUpdateGraph()" data-cy="save-or-update-graph"> <em class="icon-save icon-2x" ></em> </button> <button class="btn btn-link p-0" gdb-tooltip="{{'visual.graph.click.configure.view' | translate}}" tooltip-placement="bottom" ng-if="isUser()" ng-click="showSettings()"> <em class="icon-settings icon-2x visual-graph-settings-btn"></em> </button> </div> <div class="search-bar" ng-show="getActiveRepository() && isLicenseValid() && !isLoadingLocation() && hasActiveLocation() && 'SYSTEM' !== getActiveRepository()"> <div class="row slider mb-2" ng-show="configLoaded.startMode == 'search' && (searchVisible || !nodeSelected)" ng-cloak> <div class="col-lg-12"> <div class="card"> <div class="card-block"> <h3 class="graph-config-name">{{configLoaded.name}}</h3> <p>{{'visual.search.iri' | translate}} <span ng-if="configLoaded.name != defaultGraphConfig.name">{{'visual.graph.advanced.option' | translate}}</span> <p ng-if="configLoaded.hint">{{'hint' | translate}} {{configLoaded.hint}} </p> <search-resource-input class="incontext-search-rdf-resource" repository-namespaces="repositoryNamespaces" is-autocomplete-enabled="isAutocompleteEnabled" text-button="" visual-button="{{'rdfs.comment.show' | translate}}" visual-callback="openUri(uri)" empty="empty"> </search-resource-input> </div> </div> </div> </div> <div ng-show="!configLoaded"> <div ng-if="getActiveRepository() && !isLoadingLocation() && hasActiveLocation()" ng-cloak> <div class="card mb-2"> <div class="card-block"> <h3>{{'visual.easy.graph' | translate}}</h3> <p>{{'visual.easy.graph.info' | translate}}</p> <search-resource-input class="search-rdf-resources" repository-namespaces="repositoryNamespaces" is-autocomplete-enabled="isAutocompleteEnabled" text-button="" visual-button="{{'rdfs.comment.show' | translate}}" visual-callback="easyGraphSearch(uri)" guide-selector="graphVisualisationSearchInputNotConfigured" empty="empty"> </search-resource-input> </div> </div> <div ng-show="isFreeAccessEnabled() || isUser()" class="card mb-2"> <div class="card-block graph-configurations" ng-init="getGraphConfigs()"> <div class="clearfix"> <a ng-if="isUser()" ng-href="graphs-visualizations/config/save" class="btn btn-link pull-right create-graph-config"><span class="icon-plus"></span> {{'visual.create.graph.config' | translate}}</a> <h3>{{'visual.advanced.graph.config' | translate}}</h3> <p>{{'visual.advanced.graph.config.info' | translate}}</p> </div> <div ng-show="graphConfigs.length == 0">{{'visual.no.configs' | translate}}</div> <table class="table table-hover mb-0 graph-configurations-list" aria-describedby="Graph configurations table"> <tbody> <tr ng-repeat="config in graphConfigs"> <td width="20"> <a href ng-click="goToGraphConfig(config)"> <img ng-if="config.startMode == 'search'" src="css/images/search.png?v=3.1.0-RC3" alt="" width="64" uib-popover="{{'visual.config.search.box.starting.point' | translate}}" popover-trigger="mouseenter"> <img ng-if="config.startMode == 'node'" src="css/images/node.png?v=3.1.0-RC3" alt="" width="64" uib-popover="{{'visual.config.fixed.resource.starting.point' | translate}}" popover-trigger="mouseenter"> <img ng-if="config.startMode == 'query'" src="css/images/query.png?v=3.1.0-RC3" alt="" data-cy="graph-config-starting-point-query-results" width="64" uib-popover="{{'visual.config.query.results.starting.point' | translate}}" popover-trigger="mouseenter"> </a> </td> <td> <h5> <a href ng-click="goToGraphConfig(config)" uib-popover={{config.description}} popover-trigger="mouseenter">{{config.name}}</a> </h5> <samp class="text-muted small text-overflow d-block" ng-if="config.startMode == 'query'">{{config.startGraphQuery}}</samp> <samp class="text-muted small text-overflow d-block" ng-if="config.startMode == 'node'">{{config.startIRI}}</samp> </td> <td class="text-xs-right" ng-if="isUser() && config.owner === principal.username"> <a ng-href="graphs-visualizations/config/save/{{config.id}}" class="btn btn-link btn-edit-config" gdb-tooltip="{{'visual.edit.config' | translate}}"><span class="icon-edit"></span></a> <button type="button" ng-click="deleteConfig(config)" class="btn btn-link delete-config" gdb-tooltip="{{'visual.delete.config' | translate}}" data-cy="delete-graph-config"><span class="icon-trash"></span></button> </td> </tr> </tbody> </table> </div> </div> <div ng-show="isFreeAccessEnabled() || isUser()" data-test="saved-graphs-area" class="card mb-2"> <div class="card-block"> <h3 class="mb-2">{{'visual.saved.graphs' | translate}}</h3> <div ng-show="savedGraphs.length == 0">{{'visual.no.saved.graphs' | translate}}</div> <table class="table table-hover mb-0" ng-init="refreshSavedGraphs()" aria-describedby="Saved graphs table" data-cy="saved-graphs-table"> <tbody> <tr ng-repeat="graph in savedGraphs"> <td> <h5><a href ng-click="loadSavedGraph(graph)">{{graph.name}}</a></h5> </td> <td> <span ng-show="graph.config != 'default'">{{'visual.advanced' | translate}} <strong>{{findConfigById(graph.config).name}}</strong></span> <span ng-show="graph.config == 'default'">{{'visual.easy.graph' | translate}}</span> </td> <td class="text-xs-right"> <button class="btn btn-link" gdb-tooltip="{{'visual.get.graph.url' | translate}}" ng-click="copyToClipboardSavedGraph(graph)" data-cy="copy-to-clipboard-saved-graph"> <span class="icon-link"></span> </button> <button class="btn btn-link" ng-if="isUser() && graph.owner === principal.username" gdb-tooltip="{{'visual.rename.graph' | translate}}" ng-click="renameSavedGraph(graph)" data-cy="rename-saved-graph"> <span class="icon-edit"></span> </button> <button class="btn btn-link" ng-if="isUser() && graph.owner === principal.username" gdb-tooltip="{{'visual.delete.graph' | translate}}" ng-click="deleteSavedGraph(graph)" data-cy="delete-saved-graph"> <span class="icon-trash"></span> </button> </td> </tr> </tbody> </table> </div> </div> </div> </div> </div> </div> <keyboard-shortcuts template-url="res/graphexplore/keyboard-shortcuts.html" ng-if="nodeSelected && !loading"></keyboard-shortcuts> <div class="graph-visualization" ng-hide="loading || !nodeSelected"></div> <div onto-loader-new ng-show="loading" size="100" style="height: 75vh; display: flex;"> </div> <pageslide ps-class="rdf-info-side-panel node-info predicate-info" ps-open="showInfoPanel" onopen="onopen" onclose="onclose" ps-side="right" ps-click-outside="false" ps-custom-height="calc(100vh - 55px)" ps-size="80vw" ng-class="{'rdf-info-side-panel-expanded': pageslideExpanded}"> <div class="rdf-side-panel-content break-word-alt p-1 pt-2"> <span class="toggle-sidepanel" title="{{'visual.collapse.sidepanel' | translate}}" ng-click="toggleSidePanel()"> <em ng-class="pageslideExpanded ? 'icon-caret-right' : 'icon-caret-left'"></em> </span> <button class="close mb-1 ml-1" ng-click="closeInfoPanel()" guide-selector="close-info-panel"></button> <h3 class="hovered-parent" ng-if="showPredicates"> {{'predicates.label' | translate}} </h3> <ul class="rdf-list tab-content" ng-if="showPredicates"> <li ng-repeat='predicate in predicates track by $index' class="item clearfix break-word-alt"> <div role="{{predicate.partOfTriple ? 'button' : ''}}" ng-click="clickLink(predicate)"> <em class="{{predicate.partOfTriple ? 'fa fa-long-arrow-right triple-pred' : ''}}"></em> <span id="{{predicate.linkId + predicate.nodeIndex}}">{{splitPredicate(predicate.value)}}</span> </div> </li> </ul> <div ng-if="showFilter" class="filter-sidepanel tab-content"> <h4>{{'sidepanel.graph.settings' | translate}}</h4> <div> <div class="form-group mb-2"> <label gdb-tooltip="{{'sidepanel.limit.links.tooltip' | translate}}">{{'sidepanel.maximum.links' | translate}}</label> <div class="form-inline"> <button type="button" class="btn btn-link px-0" ng-disabled="settings['linksLimit'] < 1" ng-click="changeLimit(-1)"> <span class="icon-minus"></span> </button> <input type="number" class="form-control input-number" size="20" ng-model="settings['linksLimit']" min="0" max="1000" class="ng-pristine ng-valid ng-valid-number" ng-change="validateLinksLimit()"> <button type="button" class="btn btn-link px-0" ng-disabled="settings['linksLimit'] > 999" ng-click="changeLimit(1)"> <span class="icon-plus"></span> </button> <span style="margin-top: 5px" ng-if="invalidLimit" class="idError alert alert-danger" gdb-tooltip="{{INVALID_LINKS_TOOLTIP}}"> {{INVALID_LINKS_MSG}} </span> </div> </div> <div class="form-group mb-2" ng-show="shouldShowSettings()"> <label gdb-tooltip="{{'sidepanel.preferred.languages.for.node' | translate}}">{{'sidepanel.preferred.languages' | translate}}</label> <div class="input-group preferred-languages"> <tags-input class="wb-tags-input" ng-model="settings['languagesMap']" min-length="2" add-on-space="true" add-on-comma="true" placeholder="{{'sidepanel.add.language.tag' | translate}}"></tags-input> </div> </div> <div class="form-group mb-2"> <div class="checkbox"> <label gdb-tooltip="{{'sidepanel.include.schema.statements.tooltip' | translate}}"> <input type="checkbox" ng-model="settings['includeSchema']" class="include-schema-statements"> {{'sidepanel.include.schema.statements' | translate}} </label> </div> </div> <div class="form-group mb-2"> <div class="checkbox"> <label gdb-tooltip="{{'sidepanel.include.inferred.statements.tooltip' | translate}}"> <input type="checkbox" ng-model="settings['includeInferred']" class="include-inferred-statements"> {{'sidepanel.include.inferred.statements' | translate}} </label> </div> </div> <!-- Enable-Disable owl:sameAs checkbox --> <div class="form-group mb-2"> <div class="checkbox" gdb-tooltip="{{shouldDisableSameAs() ? 'core.require.inferred' : '' | translate}}"> <label style="{{'opacity: ' + (!settings['includeInferred'] ? '0.5' : '1')}}" > <input id="sameAsCheck" type="checkbox" ng-model="settings['sameAsState']" ng-disabled="shouldDisableSameAs()"> {{'sidepanel.expand.results.sameas' | translate}} </label> </div> </div> <!-- Enable-Disable owl:sameAs checkbox --> <div class="form-group mb-2"> <div class="checkbox"> <label gdb-tooltip="{{'sidepanel.show.pred.labels.as.links.titles.tooltip' | translate}}"> <input type="checkbox" class="show-predicate-labels" ng-model="settings['showLinksText']"> {{'sidepanel.show.pred.labels.as.links.titles' | translate}} </label> </div> </div> <uib-tabset active="active" ng-show="shouldShowSettings()"> <uib-tab> <uib-tab-heading class="nav-item" tooltip-placement="bottom"><span class="nav-link">{{'types.label' | translate}}</span></uib-tab-heading> <div class="form-group mb-2 mt-1"> <label gdb-tooltip="{{'sidepanel.preferred.types.tooltip' | translate}}">{{'sidepanel.preferred.types' | translate}}</label> <div> <tags-input class="preferred-types wb-tags-input" ng-model="settings['preferredTypesMap']" min-length="3" add-on-space="true" add-on-comma="true" placeholder="{{'sidepanel.add.preferred.type.placeholder' | translate}}" on-tag-adding="validateTag($tag, 'Preferred types', false)" on-tag-added="addedTag($tag)"></tags-input> </div> </div> <div class="form-group mb-2"> <div class="checkbox"> <label gdb-tooltip="{{'sidepanel.show.preferred.types.nodes.only.tooltip' | translate}}"> <input type="checkbox" class="show-preferred-types-only" ng-model="settings['preferredTypesOnly']"> {{'sidepanel.show.preferred.types.nodes.only' | translate}} </label> </div> </div> <div class="form-group"> <label gdb-tooltip="{{'sidepanel.ignored.types.tooltip' | translate}}">{{'sidepanel.ignored.types' | translate}}</label> <div> <tags-input class="ignored-types wb-tags-input" ng-model="settings['rejectedTypesMap']" min-length="3" add-on-space="true" add-on-comma="true" placeholder="{{'sidepanel.add.ignored.type.placeholder' | translate}}" on-tag-adding="validateTag($tag, 'Ignored types', false)" on-tag-added="addedTag($tag)"></tags-input> </div> </div> </uib-tab> <uib-tab> <uib-tab-heading class="nav-item" tooltip-placement="bottom"><span class="nav-link predicates-tab">{{'predicates.label' | translate}}</span></uib-tab-heading> <div class="form-group mb-2 mt-1"> <div> <label gdb-tooltip="{{'sidepanel.preferred.predicates.tooltip' | translate}}">{{'sidepanel.preferred.predicates' | translate}}</label> <tags-input class="preferred-predicates wb-tags-input" ng-model="settings['preferredPredicatesMap']" min-length="3" add-on-space="true" add-on-comma="true" placeholder="{{'sidepanel.add.preferred.predicate' | translate}}" on-tag-adding="validateTag($tag, 'Preferred predicates', false)" on-tag-added="addedTag($tag)"></tags-input> </div> </div> <div class="form-group mb-2"> <div class="checkbox"> <label gdb-tooltip="{{'sidepanel.show.preferred.predicates.links.only.tooltip' | translate}}"> <input type="checkbox" class="show-preferred-predicates-only" ng-model="settings['preferredPredicatesOnly']"> {{'sidepanel.show.preferred.predicates.only' | translate}} </label> </div> </div> <div class="form-group "> <label gdb-tooltip="{{'sidepanel.ignored.predicates.tooltip' | translate}}">{{'sidepanel.ignored.predicates' | translate}}</label> <div> <tags-input class="ignored-predicates wb-tags-input" ng-model="settings['rejectedPredicatesMap']" min-length="3" add-on-space="true" add-on-comma="true" placeholder="{{'sidepanel.add.ignored.predicate.placeholder' | translate}}" on-tag-adding="validateTag($tag, 'Ignored predicates', true)" on-tag-added="addedTag($tag)" template="ignored-predicates-template" tag-class="getTagClass($tag.text)"></tags-input> </div> </div> </uib-tab> </uib-tabset> <div class="mt-1 text-right"> <button type="button" class="btn btn-secondary reset-settings" ng-click="resetSettings()">{{'common.reset' | translate}}</button> <button type="submit" class="btn btn-primary save-settings-btn" ng-click="updateSettings()">{{'common.save.btn' | translate}}</button> </div> <script type="text/ng-template" id="ignored-predicates-template"> <div class="tag-template"> <div gdb-tooltip="{{$getDisplayText().endsWith('*') ? 'sidepanel.wildcard.iris' : '' | translate}}"> <span>{{$getDisplayText()}}</span> <a class="remove-button" ng-click="$removeTag()">&#xD7;</a> </div> </div> </script> </div> </div> <div ng-if="showNodeInfo" class="tab-content"> <h3 class="hovered-parent"> <a class="uri" rel="noopener" target="_blank" href="resource?{{resourceType}}={{encodedIri}}" style="text-decoration: underline;">{{rdfsLabel | htmlAsText}}</a> <button class="btn btn-link btn-sm px-0 hovered-item" style="opacity: 1" ng-click="copyToClipboard(nodeIri)" title="{{'copy.to.clipboard.modal.ok.btn' | translate}}"> <span class="icon-link"></span> </button> </h3> <rdfs-comment-label rdfs-comment="rdfsComment" expanded="expanded" always-expanded="pageslideExpanded"> </rdfs-comment-label> <div class="media mb-1"> <div class="media-left" gdb-tooltip="{{'labels.label' | translate}}" tooltip-placement="top"> <em class="icon-tag icon-lg" aria-hidden="true"></em> </div> <div class="media-body"> <span ng-repeat="l in nodeLabels"> {{l.label | htmlAsText}} <span class="language-tag" ng-if="l.lang">{{l.lang}}</span> <span ng-if="!$last"> &middot; </span> </span> </div> </div> <div class="break-word-alt" guide-selector="graph-visualization-node-info-types"> <strong>{{'types.label' | translate}}: </strong><em class="text-muted" ng-if="!nodeTypes.length">No types</em><br> <ul class="list-inline"> <li class="list-inline-item" ng-repeat="nodeType in nodeTypes" ng-class="{'lead d-block': $index == 0}"> <span class="tag tag-default tag-inverse" ng-attr-style="{{'background-color: ' + getColor(nodeType)}}">{{replaceIRIWithPrefix(nodeType)}}</span> </li> </ul> </div> <div class="mb-1" ng-show="rdfRank >= 0"> <strong>{{'view.rdf.rank.title' | translate}}: </strong> <div class="progress"> <div class="progress-bar" role="progressbar" aria-valuenow="{{rdfRank}}" aria-valuemin="0" aria-valuemax="1" style="word-break: normal; width: {{rdfRank*100}}%"> {{rdfRank}} </div> </div> </div> <div ng-if="nodeImage" class="rdf-image mb-1" ng-attr-style="{{'background-image: url(' + nodeImage + ')'}}"> </div> <list-items-search-filter filter-query-obj="propertiesQueryObj" filter-function="propertiesFilterFunc" list-items-obj="propertiesObj" list-items-not-filtered="propertiesNotFiltered" search-placeholder={{propertiesSearchPlaceholder}}> </list-items-search-filter> <div ng-switch on="propertiesObj.items.length"> <p ng-switch-when="0" class="alert alert-warning">{{'sidepanel.no.properties.found' | translate}}</p> <div ng-switch-default ui-scroll-viewport class="rdf-list"> <div ui-scroll='item in datasource' adapter="adapterContainer.adapter" class="datasource mb-1" guide-selector="graph-visualization-node-info-{{item.key}}"> <div class="item clearfix break-word-alt small">{{item.key}}</div> <div class="data-value"> <a ng-if="item.value[0].t === 'i'" href="#" ng-click="openIRI(item.value[0].v, $event)" ng-bind="item.value[0].v"></a> <span ng-if="item.value[0].t !== 'i'" ng-bind="item.value[0].v"></span> <span class="language-tag" ng-if="item.value[0].t !== 'lt:http://www.w3.org/2001/XMLSchema#string'" ng-bind="replaceIRIWithPrefix(getLiteralFromPropValue(item.value[0].t))"></span> <button class="btn btn-link btn-sm" type="button" ng-if="item.value.length > 1" ng-click="toggleMoreInfo($event, this)"> {{'rdfs.comment.show' | translate}} {{item.value.length - 1}} {{'more' | translate}} <span class="icon-caret-down"></span> </button> </div> <ul class="hidden-data-value text-secondary"> <li class="small" ng-repeat="value in item.value track by $index" ng-hide="$index == 0"> <a ng-if="value.t === 'i'" href="#" ng-click="openIRI(value.v, $event)" ng-bind="value.v"></a> <span ng-if="value.t !== 'i'" ng-bind="value.v"></span> <span class="language-tag" ng-if="value.t !== 'lt:http://www.w3.org/2001/XMLSchema#string'" ng-bind="replaceIRIWithPrefix(getLiteralFromPropValue(value.t))"></span> </li> </ul> </div> </div> </div> </div> </div> </pageslide>