Skip to content

Commit

Permalink
Added metadata configuration pages
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed Apr 26, 2021
1 parent 13b4178 commit 7ef485c
Show file tree
Hide file tree
Showing 22 changed files with 938 additions and 21 deletions.
1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"bootstrap": "^4.6.0",
"date-fns": "^2.21.1",
"http-proxy-middleware": "^1.2.0",
"lodash": "^4.17.21",
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
Expand Down
10 changes: 10 additions & 0 deletions ui/src/app/core/hooks/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}

export function useGuid() {
return uuidv4();
}
2 changes: 1 addition & 1 deletion ui/src/app/dashboard/container/ProvidersTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import { useMetadataEntities } from '../../metadata/hooks/api';
import Translate from '../../i18n/components/translate';
import ProviderList from '../../metadata/provider/component/ProviderList';
import ProviderList from '../../metadata/domain/provider/component/ProviderList';

export function ProvidersTab () {

Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/dashboard/container/SourcesTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import useFetch from 'use-http';
import Translate from '../../i18n/components/translate';
import API_BASE_PATH from '../../App.constant';

import SourceList from '../../metadata/source/component/SourceList';
import SourceList from '../../metadata/domain/source/component/SourceList';
import { useMetadataEntities } from '../../metadata/hooks/api';

export function SourcesTab () {
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/metadata/Metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { MetadataDetail } from './component/MetadataDetail';
import { MetadataHistory } from './component/MetadataHistory';
import { MetadataEditor } from './editor/MetadataEditor';
import { MetadataSelector } from './hoc/MetadataSelector';
import MetadataSchema from './hoc/MetadataSchema';
import { MetadataSchema } from './hoc/MetadataSchema';

export function Metadata () {

Expand Down
69 changes: 66 additions & 3 deletions ui/src/app/metadata/component/MetadataConfiguration.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,70 @@
import React from 'react';
import FormattedDate from '../../core/components/FormattedDate';
import Translate from '../../i18n/components/translate';
import { MetadataSection } from './MetadataSection';
import { usePropertyWidth } from './properties/hooks';

import { ObjectProperty } from './properties/ObjectProperty';

export function MetadataConfiguration ({ configuration }) {

const onEdit = (value) => console.log(value);

const columns = configuration.dates?.length || 1;
const width = usePropertyWidth(columns);

export function MetadataConfiguration () {
return (
<></>
<>
{ configuration && configuration.sections.map((section, sidx) =>
<MetadataSection section={section} key={sidx} index={ sidx } onEdit={onEdit}>
<div className="d-flex border-bottom border-light border-2 py-2">
<strong style={ {width} }><Translate value="label.option">Option</Translate></strong>
{configuration.dates.map((d, didx) =>
<strong style={ { width } } key={didx}>
{configuration.dates.length <= 1 ?
<Translate value="label.value">Value</Translate>
:
<FormattedDate date={d} />
}
</strong>
)}
</div>
<ObjectProperty property={section} columns={columns}></ObjectProperty>
</MetadataSection>
) }
</>
);
}
}

/*<ng-container *ngFor="let section of configuration.sections; let i = index;">
<section class="mb-4 config-section-list-item" *ngIf="section && section.properties && section.properties.length">
<div class="config-group">
<div class="numbered-header d-flex justify-content-start bg-light align-items-center">
<h2 class="title h4 m-0 flex-grow-1">
<span *ngIf="numbered"
class="d-inline-block px-2 py-1 mb-0 h4 number border border-secondary bg-white rounded-lg">
<span *ngIf="i + 1 < 10">0</span>{{ i + 1 }}
</span>
<span class="text ml-2">{{ section.label | translate }}</span>
</h2>
<div class="actions px-2" *ngIf="editable">
<button class="btn btn-link edit-link change-view" (click)="edit(section.id)">
<i class="fa fa-edit"></i>&nbsp;
<translate-i18n key="action.edit">Edit</translate-i18n>
</button>
</div>
</div>
<div class="p-2">
<ng-container *ngIf="section && section.properties && section.properties.length">
<div class="d-flex border-bottom border-light border-2 py-2">
<strong [ngStyle]="{'width': width}"><translate-i18n key="label.option">Option</translate-i18n></strong>
<strong *ngFor="let date of configuration.dates" [ngStyle]="{'width': width}">
<translate-i18n key="label.value" *ngIf="configuration.dates.length <= 1">Value</translate-i18n>
<span *ngIf="configuration.dates.length > 1">{{ date | date:DATE_FORMAT }}</span>
</strong>
</div>
</ng-container>
</div>
</div>
</section>*/
7 changes: 7 additions & 0 deletions ui/src/app/metadata/component/MetadataOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ import Translate from '../../i18n/components/translate';

import { MetadataObjectContext } from '../hoc/MetadataSelector';
import { MetadataHeader } from './MetadataHeader';
import { MetadataConfiguration } from './MetadataConfiguration';


import { useMetadataConfiguration } from '../hooks/configuration';

export function MetadataOptions () {

const metadata = React.useContext(MetadataObjectContext);

const { type, id } = useParams();

const configuration = useMetadataConfiguration([metadata]);

return (
<>
<h2 className="mb-4">
Expand Down Expand Up @@ -50,6 +56,7 @@ export function MetadataOptions () {
</div>
</div>*/}
</div>
<MetadataConfiguration configuration={ configuration } />
</div>
</>
);
Expand Down
42 changes: 42 additions & 0 deletions ui/src/app/metadata/component/MetadataSection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { faEdit } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React from 'react';
import Translate from '../../i18n/components/translate';

export function MetadataSection ({ section, index = -1, onEdit, children }) {
return (
<>
<section className="mb-4 config-section-list-item">
<div className="config-group">
<div className="numbered-header d-flex justify-content-start bg-light align-items-center">
<h2 className="title h4 m-0 flex-grow-1">
{index > -1 &&
<span className="d-inline-block px-2 py-1 mb-0 h4 number border border-secondary bg-white rounded-lg">
{index < 10 && <span>0</span>}
{ index + 1 }
</span>
}

<span className="text ml-2">
<Translate value={ section.label } />
</span>
</h2>
{onEdit &&
<div className="actions px-2">
<button className="btn btn-link edit-link change-view" onClick={()=>onEdit(section.id)}>
<FontAwesomeIcon icon={faEdit} />&nbsp;
<Translate value="action.edit">Edit</Translate>
</button>
</div>
}
</div>
{section && section.properties && section.properties.length &&
<div className="p-2">
{ children }
</div>
}
</div>
</section>
</>
);
}
149 changes: 149 additions & 0 deletions ui/src/app/metadata/component/properties/ArrayProperty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { faEye } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React from 'react';
import Translate from '../../../i18n/components/translate';
import { ArrayValue } from './ArrayValue';
import { usePropertyWidth } from './hooks';
import { PropertyValue } from './PropertyValue';



const isUri = (value) => {
try {
let url = new URL(value);
} catch (err) {
return false;
}
return true;
}

const getItemType = (property) => {
const items = property.items;
const def = 'default';
return items ? items.widget ? items.widget.id : def : def;
}

const isUrl = (str) => {
return isUri(str);
}

export function ArrayProperty ({ property, columns, index, onPreview }) {

const keys = property.value.reduce((val, version) => version ? version.length > val ? version.length : val : val, 0);
const range = [...Array(keys).keys()];

const dataList = property.widget?.data;

const width = usePropertyWidth(columns);

const type = getItemType(property);

return (
<>
{property.items.type === 'object' &&
<div className={ property.differences ? 'bg-diff' : '' }>
<div className="p-2" role="term"><Translate value={property.name}>{ property.name }</Translate></div>
{range.map((i) =>
<div className={`py-2 border-top ${!property.differences ? 'bg-diff' : ''}`}>
{Object.keys(property.items.properties).map((prop, n) =>
<div className="d-flex py-2" tabIndex="0">
{property.differences && <span className="sr-only">Changed:</span> }
{property.items.properties &&
<div style={{ width }} className="pl-4">
<Translate value={property.items.properties[prop].title}>{property.items.properties[prop].title}</Translate>
</div>
}
{ property.value.map((version, vIdx) =>
<PropertyValue columns={columns} value={version} />
)}
</div>
)}

</div>
)}
</div>
}
{property.items.type === 'string' &&
<>
{ (type === 'datalist' || type === 'select' || !property.width || !property.widget.id) ?
<div className={`d-flex align-items-start border-bottom border-light ${ property.differences ? 'bg-diff' : '' }`}
tabIndex="0">
{property.differences && <span className="sr-only">Changed:</span> }
<span className="p-2" role="term" style={ {width} } ><Translate value={property.name}>{ property.name }</Translate></span>
{property.value.map((v, vidx) =>
<>
{(!v || !v.length) && <p style={ {width} } className="text-secondary m-0">-</p> }
{(v && v.length > 0) &&
<ul style={ {width} } className="list-unstyled py-2 m-0">
{v.map((item, idx) =>
<li className={`text-truncate border-bottom border-light ${v.length > 1 ? 'py-2' : ''} ${'border-0'}`}>
{onPreview && isUrl(item) &&
<>
<button className="btn btn-link" onClick={() => onPreview(item)}>
<FontAwesomeIcon icon={faEye} size="lg" className="text-success" />
</button>&nbsp;
</>
}
{ item }
</li>
)}
</ul>
}
</>
)}
</div>
: property.widget && property.widget.data ?
<>
{dataList.map((item, itemIdx) =>
<div className={`d-flex justify-content-start border-bottom border-light ${ property.differences && item.differences ? 'bg-diff' : '' }`} tabIndex="0">
{item.differences && <span className="sr-only">Changed:</span> }
<span className="p-2" role="term" style={ {width} }><Translate value={item.label}>{ item.label }</Translate></span>
{ property.value.map((v, vIdx) =>
<div className="py-2" style={ {width} }>
{v && v.indexOf(item.key) > -1 && <span><Translate value="value.true">true</Translate></span> }
{(!v || !(v.indexOf(item.key) > -1)) && <span><Translate value="value.false">false</Translate></span> }
</div>
)}
</div>
)}
</>
: ''}
</>
}
</>
);
}

/*
<ng-container *ngIf="" [ngSwitch]="getItemType(property)">
<ng-container *ngSwitchCase="'datalist'">
<ng-template [ngTemplateOutlet]="listref"></ng-template>
</ng-container>
<ng-container *ngSwitchCase="'select'">
<ng-template [ngTemplateOutlet]="listref"></ng-template>
</ng-container>
<ng-container *ngSwitchDefault>
<div *ngIf="!property.widget || !property.widget.id">
<ng-template [ngTemplateOutlet]="listref"></ng-template>
</div>
<div *ngIf="property.widget && property.widget.data">
</div>
</ng-container>
</ng-container>
<ng-template #listref>
[ngbPopover]="popContent"
triggers="mouseenter:mouseleave"
popoverClass="popover-lg popover-info"
<ng-template #popContent>
<ul className="list-unstyled">
<li *ngFor="let item of v;" className="p-2 border-bottom border-light">
{{ item }}
</li>
</ul>
</ng-template>
</ng-template>
*/
38 changes: 38 additions & 0 deletions ui/src/app/metadata/component/properties/ArrayValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';

export function ArrayValue () {
return (<></>);
}

/*
<div className="d-flex align-items-start border-bottom border-light" [ngClass]="{'bg-diff': property.differences}" tabindex="0">
<span className="sr-only" *ngIf="property.differences">Changed:</span>
<span className="p-2" role="term" [ngStyle]="{'width': width}"><Translate [key]="property.name">{{ property.name }}</Translate></span>
<ng-container *ngFor="let v of property.value">
<p [ngStyle]="{'width': width}" className="text-secondary m-0" *ngIf="!v || !v.length">-</p>
<ul [ngStyle]="{'width': width}"
className="list-unstyled py-2 m-0"
[ngbPopover]="popContent"
triggers="mouseenter:mouseleave"
popoverClass="popover-lg popover-info"
*ngIf="v && v.length > 0">
<li *ngFor="let item of v; odd as isOdd; last as isLast"
className="text-truncate border-bottom border-light"
[ngClass]="{'py-2': v.length > 1, 'border-0': isLast}">
<ng-container *ngIf="preview.observers.length > 0 && isUrl(item)">
<button className="btn btn-link" (click)="preview.emit(item)">
<i className="fa fa-eye fa-lg text-success"></i>
</button>&nbsp;
</ng-container>
{{ item }}
</li>
</ul>
<ng-template #popContent>
<ul className="list-unstyled">
<li *ngFor="let item of v;" className="p-2 border-bottom border-light">
{{ item }}
</li>
</ul>
</ng-template>
</ng-container>
</div>*/
Loading

0 comments on commit 7ef485c

Please sign in to comment.