Skip to content

Commit

Permalink
GN-4693: WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
dkozickis committed May 21, 2024
1 parent e6c2ba3 commit 8965cea
Show file tree
Hide file tree
Showing 16 changed files with 354 additions and 12 deletions.
66 changes: 66 additions & 0 deletions addon/components/lpdc-plugin/lpdc-card.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{{! @glint-nocheck: not typesafe yet }}
<AuCard
@flex={{true}}
@divided={{true}}
@isOpenInitially={{true}}
@expandable={{true}}
@shadow={{true}}
@size='small'
as |c|
>
<c.header>
<AuHeading @level='3' @skin='6'>{{t 'lpdc-plugin.card.title'}}</AuHeading>
</c.header>
<c.content>
<div class='au-o-flow au-o-flow--small'>
<AuFormRow>
<AuLabel
for='searchterm'
@inline={{false}}
@required={{false}}
@error={{false}}
@warning={{false}}
>{{t 'lpdc-plugin.search.term'}}</AuLabel>
<AuNativeInput
@icon={{this.SearchIcon}}
@type='text'
@width='block'
@iconAlignment='right'
id='searchterm'
value={{this.searchText}}
placeholder={{t 'lpdc-plugin.search.placeholder'}}
{{on 'input' this.onSearchTextChange}}
/>
</AuFormRow>
</div>
</c.content>
<c.footer class='au-u-background-gray-100 au-u-padding-none'>
{{#if this.lpdcResource.isRunning}}
<AuLoader />
<span class='au-u-hidden-visually'>{{t
'lpdc-plugin.alert.loading'
}}</span>
{{else}}
{{#if this.error}}
<Common::Search::AlertLoadError
@fullSize={{false}}
@error={{this.error}}
/>
{{else}}
<AuToolbar @border='bottom' @skin='none' class='au-u-padding-small'>
<AuHeading @skin='6' @level='4'>{{t
'lpdc-plugin.card.suggestions'
}}</AuHeading>
</AuToolbar>
<div
class='citaten--decision-list au-u-margin-none au-u-padding-top-tiny au-u-padding-bottom-tiny'
>
<LpdcPlugin::LpdcList
@lpdc={{this.lpdcResource.value}}
@onLpdcInsert={{this.onLpdcInsert}}
/>
</div>
{{/if}}
{{/if}}
</c.footer>
</AuCard>
127 changes: 127 additions & 0 deletions addon/components/lpdc-plugin/lpdc-card.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { SearchIcon } from '@appuniversum/ember-appuniversum/components/icons/search';
import Component from '@glimmer/component';
import { task as trackedTask } from 'ember-resources/util/ember-concurrency';
import { restartableTask, timeout } from 'ember-concurrency';
import { tracked } from '@glimmer/tracking';
import {
fetchLpdcs,
LPDC,
type LpdcPluginConfig,
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lpdc-plugin';
import { v4 as uuidv4 } from 'uuid';
import { action } from '@ember/object';
import { SayController } from '@lblod/ember-rdfa-editor';
import { getCurrentBesluitRange } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/besluit-topic-plugin/utils/helpers';
import { sayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
import { addProperty } from '@lblod/ember-rdfa-editor/commands';
import {
RDF,
SRO,
} from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';

interface Args {
config: LpdcPluginConfig;
controller: SayController;
}

export default class LpdcCardComponent extends Component<Args> {
SearchIcon = SearchIcon;

@tracked error: unknown;

@tracked searchText = '';

/**
* Paginating the search results
*/
@tracked pageNumber = 0;
@tracked pageSize = 5;
@tracked totalSize = 0;
@tracked totalCount = 0;

get controller(): SayController {
return this.args.controller;
}

lpdcSearch = restartableTask(async () => {
await timeout(100);
this.error = null;
const abortController = new AbortController();
try {
const results = await fetchLpdcs({
filter: {
name: this.searchText,
},
pageNumber: this.pageNumber,
pageSize: this.pageSize,
config: this.args.config,
});
this.totalCount = results.totalCount;
return results.lpdc;
} catch (error) {
this.totalCount = 0;
this.error = error;
return [];
} finally {
//Abort all requests now that this task has either successfully finished or has been cancelled
abortController.abort();
}
});

lpdcResource = trackedTask(this, this.lpdcSearch, () => [
this.searchText,
this.pageNumber,
this.pageSize,
]);

@action onSearchTextChange(event: InputEvent): void {
this.searchText = (event.target as HTMLInputElement).value;
}

@action
onLpdcInsert(lpdc: LPDC) {
const rdfaId = uuidv4();

const uri = lpdc.uri;
const name = lpdc.name;

const currentBesluitRange = getCurrentBesluitRange(this.controller);

const resource =
(currentBesluitRange &&
'node' in currentBesluitRange &&
(currentBesluitRange.node.attrs.subject as string)) ||
undefined;

if (!resource) {
throw new Error('No besluit found in selection');
}

this.controller.withTransaction(
(tr) => {
const node = this.controller.schema.node(
'inline_rdfa',
{
rdfaNodeType: 'literal',
__rdfaId: rdfaId,
subject: uri,
},
[this.controller.schema.text(name)],
);

return tr.replaceSelectionWith(node);
},
{ view: this.controller.mainEditorView },
);

this.controller.doCommand(
addProperty({
resource,
property: {
predicate: SRO('bekrachtigt').full,
object: sayDataFactory.literalNode(rdfaId),
},
}),
);
}
}
18 changes: 18 additions & 0 deletions addon/components/lpdc-plugin/lpdc-list.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{! @glint-nocheck: not typesafe yet }}
{{#if @lpdc.length}}
<AuList @direction='vertical' @divider={{true}} as |Item|>
{{#each @lpdc as |lpdc|}}
<Item class='au-u-padding-left-small au-u-padding-right-small'>
<LpdcPlugin::LpdcPreview
@lpdc={{lpdc}}
@onLpdcInsert={{fn @onLpdcInsert lpdc}}
/>
</Item>
{{/each}}
</AuList>
{{else}}
<Common::Search::AlertNoItems
@fullSize={{@fullSize}}
class={{if @fullSize 'au-u-margin'}}
/>
{{/if}}
9 changes: 9 additions & 0 deletions addon/components/lpdc-plugin/lpdc-list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Component from '@glimmer/component';

import { LPDC } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lpdc-plugin';

interface Args {
onLpdcInsert: (lpdc: LPDC) => void;
}

export default class LpdcListComponent extends Component<Args> {}
19 changes: 19 additions & 0 deletions addon/components/lpdc-plugin/lpdc-preview.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{{! @glint-nocheck: not typesafe yet }}
<div class='citaten--decision-list-item' ...attributes>
<p class='citaten--decision-title'>
{{@lpdc.name}}
</p>
<div
class='au-u-flex au-u-flex--row au-u-flex--no-wrap au-u-flex--between au-u-margin-top-tiny'
>
<AuButton
@skin='link-secondary'
@icon={{this.PlusTextIcon}}
@iconAlignment='left'
class='au-u-h-functional'
{{on 'click' @onLpdcInsert}}
>
{{t 'lpdc-plugin.card.insert'}}
</AuButton>
</div>
</div>
12 changes: 12 additions & 0 deletions addon/components/lpdc-plugin/lpdc-preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Component from '@glimmer/component';
import { PlusTextIcon } from '@appuniversum/ember-appuniversum/components/icons/plus-text';

import { LPDC } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lpdc-plugin';

interface Args {
onLpdcInsert: (lpdc: LPDC) => void;
}

export default class LpdcPreviewComponent extends Component<Args> {
PlusTextIcon = PlusTextIcon;
}
63 changes: 63 additions & 0 deletions addon/plugins/lpdc-plugin/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { LPDC } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lpdc-plugin/types';

import { LpdcPluginConfig } from './index';

type LPDCInstance = {
id: string; // UUID
'@id': string; // URI
naam: {
nl: string;
};
linkedConcept: string; // URI of linked concept
linkedConceptId: string; // UUID of linked concept
linkedConceptProductnummer: string;
};

type FetchResults = {
hydraPageIndex: number;
hydraLimit: number;
hydraTotalItems: number;
hydraMember: Array<LPDCInstance>;
};

export const fetchLpdcs = async ({
config,
filter,
pageNumber,
pageSize,
}: {
pageNumber: number;
pageSize: number;
config: LpdcPluginConfig;
filter?: {
name?: string;
};
}): Promise<{
lpdc: Array<LPDC>;
totalCount: number;
}> => {
const endpoint = config?.endpoint;

const url = new URL(`${endpoint}/doc/instantie`);

if (filter?.name) {
url.searchParams.append('zoekterm', filter.name);
}

const results = await fetch(url.toString(), {
method: 'GET',
headers: {
Accept: 'application/json',
},
});

const resultJson = (await results.json()) as FetchResults;

return {
lpdc: resultJson.hydraMember.map((lpdc) => ({
uri: lpdc['@id'],
name: lpdc.naam.nl,
})),
totalCount: resultJson.hydraTotalItems,
};
};
2 changes: 2 additions & 0 deletions addon/plugins/lpdc-plugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { type LpdcPluginConfig, LPDC } from './types';
export { fetchLpdcs } from './api';
5 changes: 5 additions & 0 deletions addon/plugins/lpdc-plugin/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type LpdcPluginConfig = {
endpoint: string;
};

export type LPDC = { uri: string; name: string };
4 changes: 4 additions & 0 deletions addon/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ export const GEOSPARQL = namespace(
'http://www.opengis.net/ont/geosparql#',
'geosparql',
);
export const SRO = namespace(
'https://data.vlaanderen.be/ns/slimmeraadpleegomgeving#',
'sro',
);
1 change: 1 addition & 0 deletions app/components/lpdc-plugin/lpdc-card.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@lblod/ember-rdfa-editor-lblod-plugins/components/lpdc-plugin/lpdc-card';
1 change: 1 addition & 0 deletions app/components/lpdc-plugin/lpdc-list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@lblod/ember-rdfa-editor-lblod-plugins/components/lpdc-plugin/lpdc-list';
1 change: 1 addition & 0 deletions app/components/lpdc-plugin/lpdc-preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@lblod/ember-rdfa-editor-lblod-plugins/components/lpdc-plugin/lpdc-preview';
5 changes: 4 additions & 1 deletion tests/dummy/app/controllers/besluit-sample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ export default class BesluitSampleController extends Controller {
citation: {
type: 'nodes',
activeInNodeTypes(schema: Schema): Set<NodeType> {
return new Set<NodeType>([schema.nodes.motivering]);
return new Set<NodeType>([schema.nodes.doc]);
},
endpoint: 'https://codex.opendata.api.vlaanderen.be:8888/sparql',
decisionsEndpoint:
Expand Down Expand Up @@ -302,6 +302,9 @@ export default class BesluitSampleController extends Controller {
worship: {
endpoint: 'https://data.lblod.info/sparql',
},
lpdc: {
endpoint: 'http://localhost/lpdc-service',
},
};
}

Expand Down
Loading

0 comments on commit 8965cea

Please sign in to comment.