@startinblox/components-ds4go 4.0.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components-ds4go.css +1 -1
- package/dist/index.js +2222 -1630
- package/locales/en.xlf +58 -0
- package/package.json +1 -1
- package/src/component.d.ts +0 -5
- package/src/components/cards/ds4go-card-fact.ts +128 -0
- package/src/components/catalog/ds4go-fact-holder.ts +149 -0
- package/src/components/modal/ds4go-fact-modal.ts +217 -0
- package/src/components/solid-fact-list.ts +307 -0
- package/src/styles/cards/ds4go-card-fact.scss +112 -0
- package/src/styles/index.scss +42 -0
- package/src/styles/modal/ds4go-fact-modal.scss +161 -0
package/locales/en.xlf
CHANGED
|
@@ -404,6 +404,64 @@
|
|
|
404
404
|
<trans-unit id="sc01b3f089359860d">
|
|
405
405
|
<source>Premium tier (40 calls/month)</source>
|
|
406
406
|
</trans-unit>
|
|
407
|
+
<trans-unit id="s43d205c00fad9f7e">
|
|
408
|
+
<source>+<x id="0" equiv-text="${totalCategories - 3} ${msg("more")}"/></source>
|
|
409
|
+
</trans-unit>
|
|
410
|
+
<trans-unit id="s984a5e18d85b6d57">
|
|
411
|
+
<source><x id="0" equiv-text="${mediaCount} ${mediaCount > 1 ? msg("medias") : msg("media")}"/></source>
|
|
412
|
+
</trans-unit>
|
|
413
|
+
<trans-unit id="sc792eb5e201cf4d0">
|
|
414
|
+
<source>medias</source>
|
|
415
|
+
</trans-unit>
|
|
416
|
+
<trans-unit id="sb333b8c7b846af83">
|
|
417
|
+
<source>media</source>
|
|
418
|
+
</trans-unit>
|
|
419
|
+
<trans-unit id="s09134b07b5aacab4">
|
|
420
|
+
<source>By</source>
|
|
421
|
+
</trans-unit>
|
|
422
|
+
<trans-unit id="sa5a5964988fb72cf">
|
|
423
|
+
<source>Yes, generate it!</source>
|
|
424
|
+
</trans-unit>
|
|
425
|
+
<trans-unit id="s06444a51bc5db27f">
|
|
426
|
+
<source>AI-Video generated!</source>
|
|
427
|
+
</trans-unit>
|
|
428
|
+
<trans-unit id="s11a98d9043541ac5">
|
|
429
|
+
<source>Your AI-Generated video has been generated and is available in your Tralalère space.</source>
|
|
430
|
+
</trans-unit>
|
|
431
|
+
<trans-unit id="s59faae16854d9291">
|
|
432
|
+
<source>Video already generated</source>
|
|
433
|
+
</trans-unit>
|
|
434
|
+
<trans-unit id="sb0bf78dc704ac07e">
|
|
435
|
+
<source>Generate an AI-Video with Tralalère (5€)</source>
|
|
436
|
+
</trans-unit>
|
|
437
|
+
<trans-unit id="sbe35fa6868f5d8c6">
|
|
438
|
+
<source>Published on</source>
|
|
439
|
+
</trans-unit>
|
|
440
|
+
<trans-unit id="s2a1231c2978c689e">
|
|
441
|
+
<source>Open link on a new tab</source>
|
|
442
|
+
</trans-unit>
|
|
443
|
+
<trans-unit id="s7d83729075105484">
|
|
444
|
+
<source>Media files</source>
|
|
445
|
+
</trans-unit>
|
|
446
|
+
<trans-unit id="s2cc7cd11d9b856cd">
|
|
447
|
+
<source>Categories</source>
|
|
448
|
+
</trans-unit>
|
|
449
|
+
<trans-unit id="s53cbe88b59dd0d59">
|
|
450
|
+
<source>Updated on</source>
|
|
451
|
+
</trans-unit>
|
|
452
|
+
<trans-unit id="s32375c74e64909b5">
|
|
453
|
+
<source>Generate with Tralalère</source>
|
|
454
|
+
</trans-unit>
|
|
455
|
+
<trans-unit id="s428d999c913eaca6">
|
|
456
|
+
<source>This will create an AI-Generated video of this fact.
|
|
457
|
+
You will be charged 5€ on your account.</source>
|
|
458
|
+
</trans-unit>
|
|
459
|
+
<trans-unit id="s8bf481a0b5d8a689">
|
|
460
|
+
<source>Generating...</source>
|
|
461
|
+
</trans-unit>
|
|
462
|
+
<trans-unit id="s638b60dba93b07ef">
|
|
463
|
+
<source>Please wait while Tralalère generates your AI-Video...</source>
|
|
464
|
+
</trans-unit>
|
|
407
465
|
</body>
|
|
408
466
|
</file>
|
|
409
467
|
</xliff>
|
package/package.json
CHANGED
package/src/component.d.ts
CHANGED
|
@@ -317,11 +317,6 @@ export interface PolicyDefinition {
|
|
|
317
317
|
policy?: OdrlPolicy;
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
export interface Asset {
|
|
321
|
-
"@id": string;
|
|
322
|
-
properties?: Record<string, any>;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
320
|
// DSIF-specific types
|
|
326
321
|
export interface DSIFRootAuthoritySector {
|
|
327
322
|
sectorName: string;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import Ds4goCardFactStyle from "@styles/cards/ds4go-card-fact.scss?inline";
|
|
2
|
+
import { formatDate } from "@helpers";
|
|
3
|
+
import type { Category, Fact } from "@src/ds4go";
|
|
4
|
+
import { css, html, LitElement, nothing, unsafeCSS } from "lit";
|
|
5
|
+
import { customElement, property } from "lit/decorators.js";
|
|
6
|
+
import { msg, str } from "@lit/localize";
|
|
7
|
+
|
|
8
|
+
@customElement("ds4go-card-fact")
|
|
9
|
+
export class Ds4goCardFact extends LitElement {
|
|
10
|
+
static styles = css`
|
|
11
|
+
${unsafeCSS(Ds4goCardFactStyle)};
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
@property({ attribute: false })
|
|
15
|
+
object?: Fact;
|
|
16
|
+
|
|
17
|
+
private _getThumbnail(): string {
|
|
18
|
+
if (this.object?.enclosure) {
|
|
19
|
+
return String(this.object.enclosure);
|
|
20
|
+
}
|
|
21
|
+
// Default placeholder image
|
|
22
|
+
return "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='354' height='167' viewBox='0 0 354 167'%3E%3Crect width='354' height='167' fill='%23f0f0f0'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-family='sans-serif' font-size='14' fill='%23999'%3ENo Image%3C/text%3E%3C/svg%3E";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private _getFormattedDate(): string {
|
|
26
|
+
if (!this.object?.created_at) return "";
|
|
27
|
+
return formatDate(this.object.created_at, {
|
|
28
|
+
year: "numeric",
|
|
29
|
+
month: "long",
|
|
30
|
+
day: "numeric",
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private _getTags() {
|
|
35
|
+
const tags: {
|
|
36
|
+
label: string;
|
|
37
|
+
type: string;
|
|
38
|
+
color?: string;
|
|
39
|
+
}[] = [];
|
|
40
|
+
|
|
41
|
+
// Add categories as tags (max 3, with overflow indicator)
|
|
42
|
+
(this.object?.categories || [])?.slice(0, 3).forEach((c: Category) => {
|
|
43
|
+
if (c.name) {
|
|
44
|
+
tags.push({
|
|
45
|
+
label: c.name,
|
|
46
|
+
type: "neutral",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const totalCategories = this.object?.categories?.length || 0;
|
|
52
|
+
if (totalCategories > 3) {
|
|
53
|
+
tags.push({
|
|
54
|
+
label: msg(str`+${totalCategories - 3} ${msg("more")}`),
|
|
55
|
+
type: "neutral",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Add media count if available
|
|
60
|
+
const mediaCount = this.object?.medias?.length || 0;
|
|
61
|
+
if (mediaCount > 0) {
|
|
62
|
+
tags.push({
|
|
63
|
+
label: msg(
|
|
64
|
+
str`${mediaCount} ${mediaCount > 1 ? msg("medias") : msg("media")}`,
|
|
65
|
+
),
|
|
66
|
+
type: "information",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return tags;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
render() {
|
|
74
|
+
if (!this.object) return nothing;
|
|
75
|
+
const tags = this._getTags();
|
|
76
|
+
const formattedDate = this._getFormattedDate();
|
|
77
|
+
|
|
78
|
+
return html`<article class="vertical">
|
|
79
|
+
<header
|
|
80
|
+
class="image"
|
|
81
|
+
style='background-image: url("${this._getThumbnail()}")'
|
|
82
|
+
></header>
|
|
83
|
+
<main>
|
|
84
|
+
${formattedDate
|
|
85
|
+
? html`<div class="meta-info">
|
|
86
|
+
<span class="date">${formattedDate}</span>
|
|
87
|
+
</div>`
|
|
88
|
+
: nothing}
|
|
89
|
+
<div class="content">
|
|
90
|
+
${this.object?.name
|
|
91
|
+
? html`<div class="card-header">
|
|
92
|
+
<tems-division
|
|
93
|
+
label=${this.object?.name}
|
|
94
|
+
type="h4"
|
|
95
|
+
></tems-division>
|
|
96
|
+
</div>`
|
|
97
|
+
: nothing}
|
|
98
|
+
${this.object?.description
|
|
99
|
+
? html`<div class="card-content">
|
|
100
|
+
<tems-division
|
|
101
|
+
label=${this.object?.description}
|
|
102
|
+
type="body-m"
|
|
103
|
+
></tems-division>
|
|
104
|
+
</div>`
|
|
105
|
+
: nothing}
|
|
106
|
+
${tags.length > 0
|
|
107
|
+
? html`<div class="tags">
|
|
108
|
+
${tags.map(
|
|
109
|
+
(tag) =>
|
|
110
|
+
html`<tems-badge
|
|
111
|
+
size="sm"
|
|
112
|
+
label=${tag.label}
|
|
113
|
+
type=${tag.type}
|
|
114
|
+
color=${tag.color || nothing}
|
|
115
|
+
></tems-badge>`,
|
|
116
|
+
)}
|
|
117
|
+
</div>`
|
|
118
|
+
: nothing}
|
|
119
|
+
${this.object.author
|
|
120
|
+
? html`<div class="meta-info">
|
|
121
|
+
<span class="author">${msg("By")} ${this.object.author}</span>
|
|
122
|
+
</div>`
|
|
123
|
+
: nothing}
|
|
124
|
+
</div>
|
|
125
|
+
</main>
|
|
126
|
+
</article>`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ComponentObjectsHandler,
|
|
3
|
+
filterObjectByDateAfter,
|
|
4
|
+
filterObjectById,
|
|
5
|
+
filterObjectByInterval,
|
|
6
|
+
filterObjectByNamedValue,
|
|
7
|
+
filterObjectByType,
|
|
8
|
+
filterObjectByValue,
|
|
9
|
+
} from "@helpers";
|
|
10
|
+
import type { Fact } from "@src/ds4go";
|
|
11
|
+
import type { Resource, SearchObject, UnknownResource } from "@src/component";
|
|
12
|
+
import { css, html, nothing, type PropertyValues } from "lit";
|
|
13
|
+
import { customElement, state } from "lit/decorators.js";
|
|
14
|
+
|
|
15
|
+
@customElement("ds4go-fact-holder")
|
|
16
|
+
export class Ds4goFactHolder extends ComponentObjectsHandler {
|
|
17
|
+
static styles = css`
|
|
18
|
+
.card-grid {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: row;
|
|
21
|
+
flex-wrap: wrap;
|
|
22
|
+
gap: 20px;
|
|
23
|
+
}
|
|
24
|
+
.card-grid-vertical {
|
|
25
|
+
justify-content: stretch;
|
|
26
|
+
}
|
|
27
|
+
.card-grid-vertical ds4go-card-fact {
|
|
28
|
+
width: 354px;
|
|
29
|
+
height: auto;
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
@state()
|
|
34
|
+
search: SearchObject[] = [];
|
|
35
|
+
|
|
36
|
+
@state()
|
|
37
|
+
protected _displayObjects: Resource[] = [];
|
|
38
|
+
|
|
39
|
+
protected filter(objects: Resource[], filters: SearchObject[] = []) {
|
|
40
|
+
if (!filters || filters.length === 0 || !objects || objects.length === 0) {
|
|
41
|
+
return objects;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const groupedFilters = new Map<string, SearchObject[]>();
|
|
45
|
+
for (const filter of filters) {
|
|
46
|
+
const groupKey = filter.name;
|
|
47
|
+
const group = groupedFilters.get(groupKey) || [];
|
|
48
|
+
group.push(filter);
|
|
49
|
+
groupedFilters.set(groupKey, group);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let currentFilteredObjects = [...objects];
|
|
53
|
+
|
|
54
|
+
for (const filterGroup of groupedFilters.values()) {
|
|
55
|
+
if (currentFilteredObjects.length === 0) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const tempResults: UnknownResource[] = [];
|
|
60
|
+
for (const filter of filterGroup) {
|
|
61
|
+
switch (filter.type) {
|
|
62
|
+
case "interval":
|
|
63
|
+
tempResults.push(
|
|
64
|
+
filterObjectByInterval(
|
|
65
|
+
currentFilteredObjects,
|
|
66
|
+
filter.name,
|
|
67
|
+
filter.value,
|
|
68
|
+
),
|
|
69
|
+
);
|
|
70
|
+
break;
|
|
71
|
+
case "dateAfter":
|
|
72
|
+
tempResults.push(
|
|
73
|
+
filterObjectByDateAfter(
|
|
74
|
+
currentFilteredObjects,
|
|
75
|
+
filter.name,
|
|
76
|
+
filter.value,
|
|
77
|
+
),
|
|
78
|
+
);
|
|
79
|
+
break;
|
|
80
|
+
case "matchId":
|
|
81
|
+
tempResults.push(
|
|
82
|
+
filterObjectById(
|
|
83
|
+
currentFilteredObjects,
|
|
84
|
+
filter.name,
|
|
85
|
+
filter.value,
|
|
86
|
+
),
|
|
87
|
+
);
|
|
88
|
+
break;
|
|
89
|
+
case "matchType":
|
|
90
|
+
tempResults.push(
|
|
91
|
+
filterObjectByType(currentFilteredObjects, filter.value),
|
|
92
|
+
);
|
|
93
|
+
break;
|
|
94
|
+
case "exact":
|
|
95
|
+
tempResults.push(
|
|
96
|
+
filterObjectByNamedValue(
|
|
97
|
+
currentFilteredObjects,
|
|
98
|
+
filter.name,
|
|
99
|
+
filter.value,
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
break;
|
|
103
|
+
default:
|
|
104
|
+
tempResults.push(
|
|
105
|
+
filterObjectByValue(currentFilteredObjects, filter.value),
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
currentFilteredObjects = [...tempResults.flat()] as Resource[];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return currentFilteredObjects;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
protected _handleClickEvent(originalObj: Resource) {
|
|
116
|
+
this.dispatchEvent(new CustomEvent("clicked", { detail: originalObj }));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
willUpdate(changedProperties: PropertyValues) {
|
|
120
|
+
if (changedProperties.has("objects") || changedProperties.has("search")) {
|
|
121
|
+
if (this.objects) {
|
|
122
|
+
this._displayObjects = this.filter(this.objects, this.search);
|
|
123
|
+
} else {
|
|
124
|
+
this._displayObjects = [];
|
|
125
|
+
}
|
|
126
|
+
this.dispatchEvent(
|
|
127
|
+
new CustomEvent("result-count", {
|
|
128
|
+
detail: this._displayObjects.length,
|
|
129
|
+
}),
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
render() {
|
|
135
|
+
if (!this._displayObjects || this._displayObjects.length === 0) {
|
|
136
|
+
return nothing;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return html`<div class="card-grid card-grid-vertical">
|
|
140
|
+
${this._displayObjects.map((displayObj) => {
|
|
141
|
+
const fact = displayObj as Fact;
|
|
142
|
+
return html`<ds4go-card-fact
|
|
143
|
+
.object=${import.meta.env.DEV ? fact : nothing}
|
|
144
|
+
@click=${() => this._handleClickEvent(fact)}
|
|
145
|
+
></ds4go-card-fact>`;
|
|
146
|
+
})}
|
|
147
|
+
</div>`;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { formatDate, formatCase, OrbitComponent } from "@helpers";
|
|
2
|
+
import { localized, msg } from "@lit/localize";
|
|
3
|
+
import { Task } from "@lit/task";
|
|
4
|
+
import { PropertiesPicker } from "@src/component";
|
|
5
|
+
import type { Category, Fact } from "@src/ds4go";
|
|
6
|
+
|
|
7
|
+
import ModalStyle from "@styles/modal/ds4go-fact-modal.scss?inline";
|
|
8
|
+
import { css, html, nothing, unsafeCSS } from "lit";
|
|
9
|
+
import { customElement, state } from "lit/decorators.js";
|
|
10
|
+
|
|
11
|
+
@customElement("ds4go-fact-modal")
|
|
12
|
+
@localized()
|
|
13
|
+
export class Ds4goFactModal extends OrbitComponent {
|
|
14
|
+
constructor() {
|
|
15
|
+
super({ setupSubscriptions: false, ignoreRouter: true });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static styles = css`
|
|
19
|
+
${unsafeCSS(ModalStyle)}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
cherryPickedProperties: PropertiesPicker[] = [
|
|
23
|
+
{ key: "created_at", value: "created_at" },
|
|
24
|
+
{ key: "updated_at", value: "updated_at", cast: formatDate },
|
|
25
|
+
{ key: "name", value: "name" },
|
|
26
|
+
{ key: "description", value: "description" },
|
|
27
|
+
{ key: "author", value: "author" },
|
|
28
|
+
{ key: "link", value: "link" },
|
|
29
|
+
{ key: "enclosure", value: "enclosure" },
|
|
30
|
+
{ key: "categories", value: "categories", expand: true },
|
|
31
|
+
{ key: "medias", value: "medias", expand: true },
|
|
32
|
+
{ key: "url", value: "url" },
|
|
33
|
+
// { key: "file_size", value: "file_size" },
|
|
34
|
+
// { key: "file_type", value: "file_type" },
|
|
35
|
+
// { key: "width", value: "width" },
|
|
36
|
+
// { key: "height", value: "height" },
|
|
37
|
+
// Can't get raw review json, as store does not support datas without ids
|
|
38
|
+
// { key: "review", value: "review" },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
@state()
|
|
42
|
+
disableButton = false;
|
|
43
|
+
|
|
44
|
+
_generateVideo() {
|
|
45
|
+
this.orbit?.Swal.fire({
|
|
46
|
+
title: msg("Generate with Tralalère"),
|
|
47
|
+
text: msg(
|
|
48
|
+
"This will create an AI-Generated video of this fact.\nYou will be charged 5€ on your account.",
|
|
49
|
+
),
|
|
50
|
+
icon: "warning",
|
|
51
|
+
position: "center",
|
|
52
|
+
backdrop: true,
|
|
53
|
+
showCancelButton: true,
|
|
54
|
+
confirmButtonText: msg("Yes, generate it!"),
|
|
55
|
+
cancelButtonText: msg("Cancel"),
|
|
56
|
+
customClass: {
|
|
57
|
+
confirmButton:
|
|
58
|
+
"button text-xsmall text-bold text-center reversed color-secondary bordered icon icon-check icon-margin-right-xsmall no-background-image",
|
|
59
|
+
cancelButton:
|
|
60
|
+
"button text-xsmall text-bold text-center reversed color-primary bordered icon icon-exclamation icon-margin-right-xsmall no-background-image",
|
|
61
|
+
},
|
|
62
|
+
}).then((result: any) => {
|
|
63
|
+
if (result.isConfirmed) {
|
|
64
|
+
this.orbit?.Swal.fire({
|
|
65
|
+
title: msg("Generating..."),
|
|
66
|
+
text: msg("Please wait while Tralalère generates your AI-Video..."),
|
|
67
|
+
icon: "info",
|
|
68
|
+
showConfirmButton: false,
|
|
69
|
+
allowOutsideClick: false,
|
|
70
|
+
allowEscapeKey: false,
|
|
71
|
+
allowEnterKey: false,
|
|
72
|
+
});
|
|
73
|
+
setTimeout(() => {
|
|
74
|
+
this.orbit?.Swal.fire({
|
|
75
|
+
title: msg("AI-Video generated!"),
|
|
76
|
+
text: msg(
|
|
77
|
+
"Your AI-Generated video has been generated and is available in your Tralalère space.",
|
|
78
|
+
),
|
|
79
|
+
icon: "success",
|
|
80
|
+
});
|
|
81
|
+
this.disableButton = true;
|
|
82
|
+
}, 2500);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
_closeModal() {
|
|
88
|
+
this.dispatchEvent(new CustomEvent("close"));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
_getResource = new Task(this, {
|
|
92
|
+
task: async () => {
|
|
93
|
+
if (!this.object) return;
|
|
94
|
+
|
|
95
|
+
this.object = await this._getProxyValue(this.object["@id"]);
|
|
96
|
+
|
|
97
|
+
return this.object;
|
|
98
|
+
},
|
|
99
|
+
args: () => [this.caching, this.currentRoute],
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
render() {
|
|
103
|
+
return this._getResource.render({
|
|
104
|
+
pending: () => html`<solid-loader></solid-loader>`,
|
|
105
|
+
complete: (obj?: Fact) => {
|
|
106
|
+
if (!obj) {
|
|
107
|
+
this._closeModal();
|
|
108
|
+
return nothing;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const formattedDate = formatDate(obj.created_at, {
|
|
112
|
+
year: "numeric",
|
|
113
|
+
month: "long",
|
|
114
|
+
day: "numeric",
|
|
115
|
+
hour: "2-digit",
|
|
116
|
+
minute: "2-digit",
|
|
117
|
+
hour12: false,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return html`<div class="modal">
|
|
121
|
+
<div class="topbar">
|
|
122
|
+
<tems-button
|
|
123
|
+
@click=${this._closeModal}
|
|
124
|
+
type="outline-gray"
|
|
125
|
+
.iconLeft=${html`<icon-material-symbols-close-rounded></icon-material-symbols-close-rounded>`}
|
|
126
|
+
></tems-button>
|
|
127
|
+
<tems-button
|
|
128
|
+
@click=${this._generateVideo}
|
|
129
|
+
disabled=${this.disableButton || nothing}
|
|
130
|
+
>${this.disableButton
|
|
131
|
+
? msg("Video already generated")
|
|
132
|
+
: msg("Generate an AI-Video with Tralalère (5€)")}</tems-button
|
|
133
|
+
>
|
|
134
|
+
</div>
|
|
135
|
+
<div class="modal-content-wrapper">
|
|
136
|
+
<div class="modal-box">
|
|
137
|
+
<div class="modal-content">
|
|
138
|
+
${obj.enclosure
|
|
139
|
+
? html`<div class="cover-image">
|
|
140
|
+
<img src=${String(obj.enclosure)} alt="Cover image" />
|
|
141
|
+
</div>`
|
|
142
|
+
: nothing}
|
|
143
|
+
${obj.author
|
|
144
|
+
? html`<tems-division type="body-sm" class="author-section">
|
|
145
|
+
<div>
|
|
146
|
+
${msg("Published on")} ${formattedDate} | ${msg("By")}
|
|
147
|
+
${String(obj.author)}
|
|
148
|
+
</div>
|
|
149
|
+
</tems-division>`
|
|
150
|
+
: nothing}
|
|
151
|
+
<tems-division type="h3"
|
|
152
|
+
><div>${String(obj.name || "")}</div></tems-division
|
|
153
|
+
>
|
|
154
|
+
<tems-division type="body-m"
|
|
155
|
+
><div>${String(obj.description || "")}</div></tems-division
|
|
156
|
+
>
|
|
157
|
+
${obj.link
|
|
158
|
+
? html`<tems-division type="body-sm">
|
|
159
|
+
<tems-button
|
|
160
|
+
type="outline-color"
|
|
161
|
+
.label=${msg("Open link on a new tab")}
|
|
162
|
+
@click=${() => window.open(String(obj.link), "_blank")}
|
|
163
|
+
></tems-button>
|
|
164
|
+
</tems-division>`
|
|
165
|
+
: nothing}
|
|
166
|
+
${(obj.medias || []).length > 0
|
|
167
|
+
? html`<tems-division type="h4"
|
|
168
|
+
>${msg("Media files")}</tems-division
|
|
169
|
+
>
|
|
170
|
+
<div class="medias-gallery">
|
|
171
|
+
${(obj.medias || []).map(
|
|
172
|
+
(media: any) =>
|
|
173
|
+
html`<div class="media-item">
|
|
174
|
+
${media.url
|
|
175
|
+
? html`<img
|
|
176
|
+
src=${String(media.url)}
|
|
177
|
+
alt=${media.description || "Media"}
|
|
178
|
+
@click=${() =>
|
|
179
|
+
window.open(String(media.url), "_blank")}
|
|
180
|
+
/>`
|
|
181
|
+
: nothing}
|
|
182
|
+
</div>`,
|
|
183
|
+
)}
|
|
184
|
+
</div>`
|
|
185
|
+
: nothing}
|
|
186
|
+
${(obj.categories || []).length > 0
|
|
187
|
+
? html`<tems-division type="h4"
|
|
188
|
+
>${msg("Categories")}</tems-division
|
|
189
|
+
>
|
|
190
|
+
<div class="categories-list">
|
|
191
|
+
${(obj.categories || []).map(
|
|
192
|
+
(c: Category) =>
|
|
193
|
+
html`<tems-badge type="neutral" size="sm"
|
|
194
|
+
>${formatCase(String(c.name))}</tems-badge
|
|
195
|
+
>`,
|
|
196
|
+
)}
|
|
197
|
+
</div>`
|
|
198
|
+
: nothing}
|
|
199
|
+
<tems-division type="body-sm"
|
|
200
|
+
><div>
|
|
201
|
+
<div>${msg("Updated on")} ${String(obj.updated_at)}</div>
|
|
202
|
+
</div></tems-division
|
|
203
|
+
>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
</div>`;
|
|
208
|
+
},
|
|
209
|
+
error: (e) => {
|
|
210
|
+
if (import.meta.env.DEV) {
|
|
211
|
+
console.error(e, this);
|
|
212
|
+
}
|
|
213
|
+
return nothing;
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|