see https://github.com/psychoinformatics-de/sfb1451-projects-catalog/pull/83 and https://github.com/psychoinformatics-de/sfb1451-projects-catalog/pull/81
332 lines
16 KiB
HTML
332 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<!-- Required meta tags -->
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
|
|
|
<!-- Required Stylesheets -->
|
|
<link rel="stylesheet" type="text/css" href="/assets/style.css"/>
|
|
<link rel="stylesheet" type="text/css" href="/assets/fontawesome.min.css"/>
|
|
<link rel="stylesheet" type="text/css" href="/assets/brands.min.css"/>
|
|
<link type="text/css" rel="stylesheet" href="/assets/bootstrap.5.1.3.min.css"/>
|
|
<link type="text/css" rel="stylesheet" href="/assets/bootstrap-vue.2.21.2.min.css"/>
|
|
|
|
<!-- Required scripts -->
|
|
<!-- <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script> -->
|
|
<script src="/assets/vue.2.6.14.min.js"></script>
|
|
<script src="/assets/bootstrap-vue.2.21.2.min.js"></script>
|
|
|
|
<!-- Vue component templates -->
|
|
|
|
<!-- ================================= -->
|
|
<!-- SCHEMA ITEM: FOR SCHEMA RENDERING -->
|
|
<!-- ================================= -->
|
|
<script type="text/x-template" id="schema-item">
|
|
<b-card no-body class="border-0" v-show="item">
|
|
<b-card-body class="pb-0">
|
|
<!-- ITEM TITLE -->
|
|
<b-card-title>
|
|
<span v-if="isschema">
|
|
<u>Schema: {{item.title}}</u>
|
|
</span>
|
|
<span v-else>
|
|
<small>
|
|
<span class="item-line"></span>
|
|
<span v-if="'title' in item">
|
|
<u>{{item.title}}</u>
|
|
</span>
|
|
<span v-else>
|
|
<u>{{name}}</u>
|
|
</span>
|
|
</small>
|
|
</span>
|
|
<small>
|
|
<span v-if="'type' in item">
|
|
<span v-if="Array.isArray(item.type)">
|
|
<span v-for="tp in item.type">
|
|
<span :style="'background-color:'+type_colors[tp]+';'" class="type-indicator mfont" :id="parent_name+'-'+name+'-'+tp" v-b-tooltip.hover.righttop="'type: '+tp">{{type_icons[tp]}}</span>
|
|
</span>
|
|
</span>
|
|
<span v-else :style="'background-color:'+type_colors[item.type]+';'" class="type-indicator mfont" :id="parent_name+'-'+name+'-'+item.type" v-b-tooltip.hover.righttop="'type: '+item.type">{{type_icons[item.type]}}</span>
|
|
</span>
|
|
<span v-if="'$ref' in item" :style="'background-color:'+type_colors['$ref']+';'" class="type-indicator mfont" :id="parent_name+'-'+name+'-ref'" v-b-tooltip.hover.righttop="'type: $ref'">{{type_icons['$ref']}}</span>
|
|
<span v-if="!isschema">
|
|
<span v-if="requireditems && requireditems.indexOf(name) >= 0" class="type-indicator-required mfont">
|
|
required</span>
|
|
<span v-else class="type-indicator-optional mfont">
|
|
[optional]</span>
|
|
</span>
|
|
</small>
|
|
<!-- <b-button v-if="isschema" size ="sm" class="pt-0 pb-0 mb-0" variant="outline-dark" @click="$emit('showmetaform')"><i class="fas fa-pen-to-square"></i> Enter metadata</b-button> -->
|
|
<span v-if="isschema"> <b-button size ="sm" class="pt-0 pb-0 mb-0" variant="outline-dark" @click="$emit('resolveschema')"><i class="fas fa-download"></i> Resolve schema</b-button></span>
|
|
</b-card-title>
|
|
<!-- ITEM ANNOTATIONS AND VALIDATIONS -->
|
|
<b-card-text :class="isschema ? 'mb-1' : 'mb-1 sfont'">
|
|
<b-container style="padding-left: 0;">
|
|
<b-row>
|
|
<b-col cols="6">
|
|
<b-container style="padding-left: 0;">
|
|
<span v-for="kw in defaults.schema_keywords.concat(defaults.instance_keywords).concat(defaults.schema_annotations).concat(defaults.additional_keywords)">
|
|
<b-row v-if="kw in item">
|
|
<b-col cols="3"><strong>{{kw}}:</strong></b-col>
|
|
<b-col>
|
|
<span v-if="kw == '$ref'">
|
|
<a class="reflink" :style="'--refcolor:' + type_colors['$ref']+';'" @click="$emit('refselected', item[kw])">{{item[kw]}}</a>
|
|
</span>
|
|
<span v-else>
|
|
{{item[kw]}}
|
|
</span>
|
|
</b-col>
|
|
</b-row>
|
|
</span>
|
|
<span v-if="(Array.isArray(item.type) ? item.type : [item.type]).indexOf('array') >= 0">
|
|
<b-row>
|
|
<b-col cols="3"><strong>Array Item Type:</strong></b-col>
|
|
<b-col><span v-if="'items' in item && 'type' in item.items">{{item.items.type}}</span><span v-else><em>unspecified</em></span></b-col>
|
|
</b-row>
|
|
</span>
|
|
</b-container>
|
|
</b-col>
|
|
<b-col>
|
|
<span v-if="'type' in item && hasvalidations">
|
|
<em>Validations:</em><br>
|
|
<span v-for="tp in (Array.isArray(item.type) ? item.type : [item.type])">
|
|
<span v-for="(kw, index) in Object.keys(defaults.validation_keywords[tp])">
|
|
<span v-if="kw in item"><pre class="validation-text">{{kw}}: {{item[kw]}}</pre></span>
|
|
</span>
|
|
</span>
|
|
<span v-for="(kw, index) in Object.keys(defaults.validation_keywords.any)">
|
|
<span v-if="kw in item && kw != 'type'"><pre class="validation-text">{{kw}}: {{item[kw]}}</pre></span>
|
|
</span>
|
|
</span>
|
|
</b-col>
|
|
</b-row>
|
|
</b-container>
|
|
</b-card-text>
|
|
<!-- OBJECT ITEM: PROPERTIES -->
|
|
<b-card-text>
|
|
<span v-if="'type' in item && 'properties' in item">
|
|
<span v-if="(Array.isArray(item.type) ? item.type : [item.type]).indexOf('object') >= 0">
|
|
<b-button size="sm" class="pt-0 pb-0" variant="outline-secondary" v-b-toggle="parent_name+'-'+name+'-props'">Properties</b-button>
|
|
<b-collapse :id="parent_name+'-'+name+'-props'">
|
|
<b-card no-body border-variant="default">
|
|
<schema-item v-for="key in Object.keys(item.properties)" :name="key" :parent_name="name" :item="item.properties[key]" :defaults="defaults" :requireditems="item.required" :isschema="false" v-on="$listeners"></schema-item>
|
|
</b-card>
|
|
</b-collapse>
|
|
</span>
|
|
</span>
|
|
<!-- ARRAY ITEM: DETAILS -->
|
|
<span v-if="'type' in item">
|
|
<span v-if="(Array.isArray(item.type) ? item.type : [item.type]).indexOf('array') >= 0">
|
|
<span v-if="'items' in item && 'type' in item.items && item.items.type == 'object'">
|
|
<b-button size="sm" class="pt-0 pb-0" variant="outline-secondary" v-b-toggle="parent_name+'-'+name+'items-props'">Array Item Properties</b-button>
|
|
<b-collapse :id="parent_name+'-'+name+'items-props'">
|
|
<b-card no-body border-variant="default">
|
|
<schema-item v-for="key in Object.keys(item.items.properties)" :name="key" :parent_name="name" :item="item.items.properties[key]" :defaults="defaults" :requireditems="item.items.required" :isschema="false" v-on="$listeners"></schema-item>
|
|
</b-card>
|
|
</b-collapse>
|
|
</span>
|
|
</span>
|
|
</span>
|
|
</b-card-text>
|
|
</b-card-body>
|
|
</b-card>
|
|
</script>
|
|
|
|
|
|
<!-- ================================= -->
|
|
<!-- T-INPUT: FOR METADATA ITEM INPUT -->
|
|
<!-- ================================= -->
|
|
<script type="text/x-template" id="input-template">
|
|
<b-form-group
|
|
:id="obj.input_group_id"
|
|
:label-for="obj.input_id"
|
|
ref="formgroup"
|
|
>
|
|
<template v-slot:label>
|
|
<strong>{{(i+1).toString() + '. ' + input_label }}</strong> <i class="fas fa-circle-info text-secondary" v-b-popover.hover.topleft="obj.description"></i> <span class="text-danger" v-if="obj.required">*</span>
|
|
</template>
|
|
<span v-if="obj.input_type == 'array'">
|
|
<b-table ref="itemtable" responsive striped bordered hover small v-bind:items="obj.value"
|
|
v-bind:fields="array_fields"
|
|
style="margin-bottom: 5px;">
|
|
<!-- Options column -->
|
|
<template #cell(opts)="data">
|
|
<div style="text-align: right">
|
|
<b-button variant="outline-dark" size="sm" @click="addItemModal(data.index)"><i class="fas fa-pen-to-square"></i></b-button>
|
|
<b-button variant="outline-dark" size="sm" @click="removeItemModal(data.index)" ><i class="fas fa-trash"></i></b-button>
|
|
</div>
|
|
</template>
|
|
</b-table>
|
|
<div style="text-align: right;">
|
|
<b-button variant="outline-dark" size="sm" @click="addItemModal({})">Add item</b-button>
|
|
</div>
|
|
</span>
|
|
<span v-else-if="obj.input_type == 'object'">
|
|
<b-card no-body>
|
|
<b-container>
|
|
<span v-for="ch in obj.children">
|
|
<b-row >
|
|
<b-col cols="3"><em>{{ch.label}}:</em></b-col>
|
|
<b-col>
|
|
<span v-if="ch.value">{{ch.value}}</span><span v-else>-</span>
|
|
</b-col>
|
|
</b-row>
|
|
</span>
|
|
</b-container>
|
|
</b-card>
|
|
<div style="text-align: right;">
|
|
<b-button variant="outline-dark" size="sm" @click="addItemModal(obj)">Add/edit data</b-button>
|
|
</div>
|
|
</span>
|
|
<span v-else>
|
|
<b-form-input :id="obj.input_id" :type="obj.input_type" v-model="obj.value" :placeholder="obj.placeholder" :required="obj.required"></b-form-input>
|
|
</span>
|
|
<b-modal ref="additem" @ok="saveItem()" title="Add/Edit item" size="xl" :hideHeaderClose="true" hide-footer>
|
|
<b-container fluid >
|
|
<span v-if="obj.input_type == 'array' && obj.children[0]">
|
|
<span v-if="obj.children[0].input_type == 'object'">
|
|
<schema-form :title="obj.label" :form_config="obj.children[0]" :toplevel="false" @closemodal="closeItemModal"></schema-form>
|
|
</span>
|
|
<span v-else>
|
|
<schema-form :title="obj.label" :form_config="obj" :toplevel="false" @closemodal="closeItemModal"></schema-form>
|
|
</span>
|
|
</span>
|
|
<span v-if="obj.input_type == 'array' && !obj.children[0]">
|
|
<b-form-group
|
|
:id="obj.input_group_id"
|
|
:label="obj.form_field"
|
|
:label-for="obj.input_id">
|
|
<b-form-input :id="obj.input_id" type="text"></b-form-input>
|
|
</b-form-group>
|
|
</span>
|
|
<span v-if="obj.input_type == 'object' && obj.children">
|
|
<schema-form :title="obj.label" :form_config="obj" :toplevel="false" @closemodal="closeItemModal"></schema-form>
|
|
</span>
|
|
</b-container>
|
|
</b-modal>
|
|
|
|
</b-form-group>
|
|
</script>
|
|
|
|
|
|
<!-- ================================= -->
|
|
<!-- SCHEMA-FORM: METADATA INPUT FORM -->
|
|
<!-- ================================= -->
|
|
<script type="text/x-template" id="form-template">
|
|
<b-card border-variant="dark">
|
|
<b-card-title>
|
|
<u>{{title}}</u>
|
|
</b-card-title>
|
|
<br>
|
|
<b-form @submit="onSubmit" @reset="onReset">
|
|
<span v-for="(field, i) in form_config.children">
|
|
<t-input ref="forminput" v-bind:obj="field" :i="i"></t-input>
|
|
<br>
|
|
</span>
|
|
<br><br>
|
|
<div style="text-align: right">
|
|
<span v-if="toplevel">
|
|
<b-button type="submit" variant="outline-dark"><i class="fas fa-download"></i> Download metadata</b-button>
|
|
</span>
|
|
<span v-else>
|
|
<b-button type="submit" variant="outline-dark"><i class="far fa-floppy-disk"></i> Save metadata</b-button>
|
|
</span>
|
|
<b-button type="reset" variant="outline-dark"><i class="fas fa-arrow-rotate-left"></i> Reset</b-button>
|
|
<b-button variant="outline-dark" @click="$emit('closemodal')"><i class="fas fa-xmark"></i> Cancel</b-button>
|
|
</div>
|
|
</b-form>
|
|
<br>
|
|
</b-card>
|
|
</script>
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<!-- ### -->
|
|
<!-- ### -->
|
|
<!-- ### -->
|
|
<!-- ================ -->
|
|
<!-- MAIN APPLICATION -->
|
|
<!-- ================ -->
|
|
<body>
|
|
<b-container id="vue_app">
|
|
<!-- HEADER -->
|
|
<b-container style="margin-top:20px;">
|
|
<b-row align-v="end">
|
|
<b-col cols="9">
|
|
<span><a @click="gotoHome"><img :src="'artwork/catalog_logo.svg'" class="d-inline-block" alt="datalad" style="width:100%;"></a></span>
|
|
</b-col>
|
|
<b-col cols="1"></b-col>
|
|
<b-col cols="2" align-h="end">
|
|
<b-navbar toggleable="lg" type="light" variant="outline-dark">
|
|
|
|
<b-navbar-toggle target="navbar-toggle-collapse">
|
|
</b-navbar-toggle>
|
|
<b-collapse id="navbar-toggle-collapse" is-nav>
|
|
<b-navbar-nav class="ml-auto mb-0 xlfont">
|
|
<b-nav-item v-b-tooltip.hover title="About" @click="gotoAbout"><i class="fas fa-info-circle"></i></b-nav-item>
|
|
<b-nav-item v-b-tooltip.hover title="Read documentation" @click="gotoExternal('docs')"><i class="fas fa-file-alt"></i></b-nav-item>
|
|
<b-nav-item v-b-tooltip.hover title="View code base" @click="gotoExternal('github')"><i class="fab fa-github"></i></b-nav-item>
|
|
<b-nav-item v-b-tooltip.hover title="Follow on Mastodon" @click="gotoExternal('mastodon')"><i class="fab fa-mastodon"></i></b-nav-item>
|
|
<b-nav-item v-b-tooltip.hover title="Follow on X (Twitter)" @click="gotoExternal('x')"><i class="fab fa-x-twitter"></i></b-nav-item>
|
|
</b-navbar-nav>
|
|
</b-collapse>
|
|
</b-navbar>
|
|
</b-col>
|
|
</b-row>
|
|
</b-container>
|
|
<br>
|
|
<!-- LIST OF AVAILABLE SCHEMAS + UPLOAD -->
|
|
<b-card no-body border-variant="dark" v-show="schemas_ready">
|
|
<b-card-body>
|
|
<b-card-title>
|
|
<u>Available schemas</u>
|
|
</b-card-title>
|
|
<b-card-text>
|
|
<b-container>
|
|
<b-row>
|
|
<b-col>
|
|
<small>
|
|
<b-list-group>
|
|
<b-list-group-item button v-for="s in Object.keys(schema_files)" @click="selectSchema(s)" :style="s==schema_name ? 'background-color: #fba30454': ''">{{s}}</b-list-group-item>
|
|
</b-list-group>
|
|
</small>
|
|
</b-col>
|
|
<b-col>
|
|
</b-col>
|
|
</b-row>
|
|
</b-container>
|
|
</b-card-text>
|
|
</b-card-body>
|
|
</b-card>
|
|
<br>
|
|
|
|
<!-- SELECTED SCHEMA RENDERING -->
|
|
<b-card no-body border-variant="dark" v-show="schemas_ready">
|
|
<schema-item
|
|
:name="schema.title"
|
|
:parent_name="''"
|
|
:item="schema"
|
|
:defaults="defaults"
|
|
:requireditems="schema.required"
|
|
:isschema="true"
|
|
@refselected="selectRefSchema"
|
|
@showmetaform="addMetadata(schema)"
|
|
@resolveschema="getResolvedSchema(schema)"></schema-item>
|
|
<br>
|
|
</b-card>
|
|
<br>
|
|
|
|
<!-- SELECTED SCHEMA FORM INPUT -->
|
|
<schema-form v-show="show_form" :title="schema.title" :form_config="form_config" :toplevel="true"></schema-form>
|
|
|
|
</b-container>
|
|
<br><br><br><br>
|
|
<!-- Start running your app -->
|
|
<script src="/assets/display_schema.js"></script>
|
|
</body>
|
|
</html>
|