Skip to content

Commit

Permalink
GN-4693: Insert LPDC
Browse files Browse the repository at this point in the history
  • Loading branch information
dkozickis committed May 21, 2024
1 parent e6c2ba3 commit 5e007a0
Show file tree
Hide file tree
Showing 18 changed files with 485 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/hungry-badgers-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lblod/ember-rdfa-editor-lblod-plugins": minor
---

GN-4693: Insert LPDC
19 changes: 19 additions & 0 deletions addon/components/lpdc-plugin/lpdc-insert.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{{! @glint-nocheck: not typesafe yet }}
<li class='au-c-list__item'>
<AuButton
@icon={{this.AddIcon}}
@iconAlignment='left'
@skin='link'
{{on 'click' this.openModal}}
@disabled={{this.isButtonDisabled}}
>
{{t 'lpdc-plugin.insert.title'}}
</AuButton>
</li>

<LpdcPlugin::LpdcModal
@open={{this.showModal}}
@closeModal={{this.closeModal}}
@config={{@config}}
@onLpdcInsert={{this.onLpdcInsert}}
/>
94 changes: 94 additions & 0 deletions addon/components/lpdc-plugin/lpdc-insert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { action } from '@ember/object';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { AddIcon } from '@appuniversum/ember-appuniversum/components/icons/add';

import { SayController } from '@lblod/ember-rdfa-editor';
import { sayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
import { addProperty } from '@lblod/ember-rdfa-editor/commands';
import {
LPDC,
type LpdcPluginConfig,
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lpdc-plugin';
import { v4 as uuidv4 } from 'uuid';
import { getCurrentBesluitRange } from '../../plugins/besluit-topic-plugin/utils/helpers';
import { SRO } from '../../utils/constants';

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

export default class LpdcPluginsInsertComponent extends Component<Args> {
AddIcon = AddIcon;

@tracked showModal = false;

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

@action
openModal() {
this.controller.focus();
this.showModal = true;
}

@action
closeModal() {
this.showModal = false;
}

get isButtonDisabled() {
return !getCurrentBesluitRange(this.controller);
}

@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),
},
}),
);

this.closeModal();
}
}
44 changes: 44 additions & 0 deletions addon/components/lpdc-plugin/lpdc-modal.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{{! @glint-nocheck: not typesafe yet }}
<AuModal
@modalOpen={{@open}}
@closeModal={{this.closeModal}}
@title={{t 'lpdc-plugin.modal.title'}}
@size='large'
@padding='none'
as |modal|
>
<modal.Body>
<AuMainContainer class='snippet-modal--main-container' as |mc|>
<mc.content @scroll={{true}}>
<div class='snippet-modal--list-container'>
{{#if this.error}}
<Common::Search::AlertLoadError
@error={{this.error}}
class='au-u-margin-top-none'
/>
{{else}}
<LpdcPlugin::LpdcTableView
@lpdc={{this.lpdcResource.value}}
@isLoading={{this.lpdcResource.isRunning}}
@onLpdcInsert={{@onLpdcInsert}}
@nameFilter={{this.searchText}}
@pageNumber={{this.pageNumber}}
/>
{{/if}}
</div>
<AuToolbar
@border='top'
@size='large'
@nowrap={{true}}
@reverse={{true}}
>
<AuButtonGroup>
<AuButton @skin='secondary' {{on 'click' this.closeModal}}>
{{t 'lpdc-plugin.modal.close'}}
</AuButton>
</AuButtonGroup>
</AuToolbar>
</mc.content>
</AuMainContainer>
</modal.Body>
</AuModal>
79 changes: 79 additions & 0 deletions addon/components/lpdc-plugin/lpdc-modal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { restartableTask, timeout } from 'ember-concurrency';
import { task as trackedTask } from 'ember-resources/util/ember-concurrency';

import { tracked } from '@glimmer/tracking';

import {
fetchLpdcs,
LPDC,
type LpdcPluginConfig,
} from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lpdc-plugin';
import { trackedReset } from 'tracked-toolbox';

interface Signature {
Args: {
config: LpdcPluginConfig;
onLpdcInsert: (lpdc: LPDC) => void;
closeModal: () => void;
open: boolean;
};
}

export default class LpdcPluginModalComponent extends Component<Signature> {
// Filtering
@tracked searchText: string | null = null;

// Display
@tracked error: unknown;

/**
* Paginating the search results
*/
@trackedReset('searchText')
pageNumber = 0;

get config() {
return this.args.config;
}

@action
closeModal() {
this.args.closeModal();
}

lpdcSearch = restartableTask(async () => {
await timeout(100);
this.error = null;
const abortController = new AbortController();
try {
const results = await fetchLpdcs({
filter: {
name: this.searchText ?? undefined,
},
pageNumber: this.pageNumber,
config: this.args.config,
});

return Object.assign(results.lpdc, {
meta: results.meta,
});
} catch (error) {
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,
]);

@action onSearchTextChange(event: InputEvent): void {
this.searchText = (event.target as HTMLInputElement).value;
}
}
53 changes: 53 additions & 0 deletions addon/components/lpdc-plugin/lpdc-table-view.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{{! @glint-nocheck: not typesafe yet }}
<div class='say-snippet-lists-table'>
{{#let
(t 'lpdc-plugin.table.header.name')
(t 'lpdc-plugin.search.placeholder')
(t 'lpdc-plugin.modal.insert')
as |name search insert|
}}
<AuDataTable
@content={{this.lpdc}}
@isLoading={{@isLoading}}
@noDataMessage={{t 'common.search.no-results'}}
@sort={{@sort}}
@page={{@pageNumber}}
@size={{25}}
as |t|
>
<t.menu as |menu|>
<menu.general>
<AuToolbar class='au-o-box' as |Group|>
<Group />
<Group class='au-c-toolbar__group--center'>
<AuDataTableTextSearch
@wait={{500}}
@filter={{@nameFilter}}
@placeholder={{search}}
/>
</Group>
</AuToolbar>
</menu.general>
</t.menu>
<t.content as |c|>
<c.header>
<AuDataTableThSortable
@field='name'
@label={{name}}
@currentSorting={{@sort}}
@class='data-table__header-title'
/>
<th class='snippet-list-table-select-column'>{{insert}}</th>
</c.header>
<c.body as |row|>
<td>{{row.name}}</td>
<td class='snippet-list-table-select-column'>
<AuButton {{on 'click' (fn @onLpdcInsert row)}}>
{{insert}}
</AuButton>
</td>
</c.body>
</t.content>
</AuDataTable>
{{/let}}
</div>
23 changes: 23 additions & 0 deletions addon/components/lpdc-plugin/lpdc-table-view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Component from '@glimmer/component';
import { LPDC } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/lpdc-plugin';

interface Args {
lpdc: LPDC[] & {
meta: {
count: number;
pagination: { first: { number: number }; last: { number: number } };
};
};
isLoading: boolean;
onLpdcInsert: (lpdc: LPDC) => void;
// Filtering
nameFilter: string | null;
// Pagination
pageNumber: number;
}

export default class LpdcTableViewComponent extends Component<Args> {
get lpdc() {
return this.args.lpdc;
}
}
Loading

0 comments on commit 5e007a0

Please sign in to comment.