@uxland/primary-shell 1.1.0 → 2.0.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/README.md +231 -0
- package/dist/UI/components/clinical-monitoring/clinical-monitoring.d.ts +11 -0
- package/dist/UI/components/clinical-monitoring/template.d.ts +3 -0
- package/dist/UI/components/index.d.ts +1 -0
- package/dist/UI/components/primaria-breadcumbs/primaria-breadcumbs.d.ts +9 -0
- package/dist/UI/components/primaria-breadcumbs/template.d.ts +3 -0
- package/dist/UI/components/primaria-shell/primaria-shell.d.ts +14 -0
- package/dist/UI/components/primaria-shell/template.d.ts +3 -0
- package/dist/UI/components/title-view/template.d.ts +3 -0
- package/dist/UI/components/title-view/title-view.d.ts +9 -0
- package/dist/UI/index.d.ts +2 -0
- package/dist/UI/shared-components/dss-container/dss-container.d.ts +7 -0
- package/dist/UI/shared-components/index.d.ts +2 -0
- package/dist/UI/shared-components/primaria-content-switcher/primaria-content-switcher.d.ts +14 -0
- package/dist/UI/shared-components/primaria-interaction/components/dialog-component.d.ts +20 -0
- package/dist/UI/shared-components/primaria-interaction/components/notifier-component.d.ts +12 -0
- package/dist/UI/shared-components/primaria-interaction/confirm-mixin.d.ts +16 -0
- package/dist/UI/shared-components/primaria-interaction/confirm.d.ts +3 -0
- package/dist/UI/shared-components/primaria-interaction/index.d.ts +4 -0
- package/dist/UI/shared-components/primaria-interaction/notify.d.ts +4 -0
- package/dist/UI/shared-components/primaria-interaction/typings.d.ts +28 -0
- package/dist/UI/shared-components/primaria-menu-item/primaria-menu-item.d.ts +10 -0
- package/dist/UI/shared-components/primaria-menu-item/template.d.ts +3 -0
- package/dist/UI/shared-components/primaria-text-editor/primaria-rich-text-editor.d.ts +57 -0
- package/dist/UI/shared-components/primaria-text-editor/template.d.ts +1 -0
- package/dist/UI/shared-components/primaria-text-editor/utils.d.ts +1 -0
- package/dist/UI/styles/theme/apply-theme.d.ts +1 -0
- package/dist/api/api.d.ts +27 -0
- package/dist/api/broker/factory.d.ts +3 -0
- package/dist/api/broker/factory.test.d.ts +1 -0
- package/dist/api/broker/primaria-broker.d.ts +5 -0
- package/dist/api/global-state/global-state.d.ts +35 -0
- package/dist/api/global-state/global-state.test.d.ts +1 -0
- package/dist/api/interaction-manager/interaction.d.ts +8 -0
- package/dist/api/localization/localization.test.d.ts +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +26335 -239
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +8647 -0
- package/dist/index.umd.cjs.map +1 -0
- package/dist/initializer.d.ts +1 -0
- package/dist/locales.d.ts +15 -0
- package/dist/plugin.d.ts +6 -0
- package/dist/region-manager.d.ts +16 -0
- package/dist/regions.d.ts +14 -0
- package/dist/style.css +3 -0
- package/package.json +23 -15
- package/src/UI/components/clinical-monitoring/clinical-monitoring.ts +28 -0
- package/src/UI/components/clinical-monitoring/styles.scss +29 -0
- package/src/UI/components/clinical-monitoring/template.ts +12 -0
- package/src/UI/components/index.ts +5 -0
- package/src/UI/components/primaria-breadcumbs/primaria-breadcumbs.ts +27 -0
- package/src/UI/components/primaria-breadcumbs/styles.scss +25 -0
- package/src/UI/components/primaria-breadcumbs/template.ts +15 -0
- package/src/UI/components/primaria-shell/primaria-shell.ts +37 -0
- package/src/UI/components/primaria-shell/styles.scss +68 -0
- package/src/UI/components/primaria-shell/template.ts +94 -0
- package/src/UI/components/title-view/styles.scss +5 -0
- package/src/UI/components/title-view/template.ts +6 -0
- package/src/UI/components/title-view/title-view.ts +23 -0
- package/src/UI/images/Gencat_Logotip.svg +70 -0
- package/src/UI/images/Salut_Logotip.svg +8 -0
- package/src/UI/index.ts +2 -0
- package/src/UI/shared-components/design-system.css +1 -0
- package/src/UI/shared-components/dss-container/dss-container.ts +32 -0
- package/src/UI/shared-components/dss-container/styles.scss +23 -0
- package/src/UI/shared-components/index.ts +5 -0
- package/src/UI/shared-components/primaria-content-switcher/primaria-content-switcher.ts +79 -0
- package/src/UI/shared-components/primaria-interaction/components/dialog-component-styles.scss +155 -0
- package/src/UI/shared-components/primaria-interaction/components/dialog-component.ts +120 -0
- package/src/UI/shared-components/primaria-interaction/components/notifier-component-styles.scss +128 -0
- package/src/UI/shared-components/primaria-interaction/components/notifier-component.ts +73 -0
- package/src/UI/shared-components/primaria-interaction/confirm-mixin.ts +39 -0
- package/src/UI/shared-components/primaria-interaction/confirm.ts +30 -0
- package/src/UI/shared-components/primaria-interaction/index.ts +4 -0
- package/src/UI/shared-components/primaria-interaction/notify.ts +153 -0
- package/src/UI/shared-components/primaria-interaction/typings.ts +32 -0
- package/src/UI/shared-components/primaria-menu-item/primaria-menu-item.ts +25 -0
- package/src/UI/shared-components/primaria-menu-item/styles.scss +10 -0
- package/src/UI/shared-components/primaria-menu-item/template.ts +8 -0
- package/src/UI/shared-components/primaria-text-editor/primaria-rich-text-editor.ts +230 -0
- package/src/UI/shared-components/primaria-text-editor/styles.scss +972 -0
- package/src/UI/shared-components/primaria-text-editor/template.ts +8 -0
- package/src/UI/shared-components/primaria-text-editor/utils.ts +39 -0
- package/src/UI/styles/_flex-layout.scss +203 -0
- package/src/UI/styles/_normalize.scss +3 -0
- package/src/UI/styles/_variables.scss +40 -0
- package/src/UI/styles/styles.scss +3 -0
- package/src/UI/styles/theme/apply-theme.ts +11 -0
- package/src/api/api.ts +63 -0
- package/src/api/broker/factory.test.ts +124 -0
- package/src/api/broker/factory.ts +122 -0
- package/src/api/broker/primaria-broker.ts +11 -0
- package/src/api/global-state/global-state.test.ts +53 -0
- package/src/api/global-state/global-state.ts +49 -0
- package/src/api/interaction-manager/interaction.ts +21 -0
- package/src/api/localization/localization.test.ts +61 -0
- package/src/api/localization/localization.ts +54 -0
- package/src/constants.ts +2 -0
- package/src/index.ts +12 -0
- package/src/initializer.ts +39 -4
- package/src/locales.ts +24 -0
- package/src/plugin.ts +9 -0
- package/src/region-manager.ts +155 -0
- package/src/regions.ts +17 -6
- package/dist/index.mjs +0 -3209
- package/index.ts +0 -3
- package/src/primary-shell.ts +0 -78
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { LitElement, css, html, nothing, unsafeCSS } from "lit";
|
|
2
|
+
import { customElement, property, query } from "lit/decorators.js";
|
|
3
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
4
|
+
import { IConfirmMixin } from "../confirm-mixin";
|
|
5
|
+
import { ConfirmOptions, CustomConfirmOptions } from "../typings";
|
|
6
|
+
import styles from "./dialog-component-styles.scss?inline";
|
|
7
|
+
|
|
8
|
+
const renderActions = (props: DialogComponent) => {
|
|
9
|
+
if (!props.options.acceptLabel && !props.options.cancelLabel) return nothing;
|
|
10
|
+
return html`
|
|
11
|
+
<div class="dialog__actions">
|
|
12
|
+
<button @click="${props._cancel}" ?hidden=${!props.options.cancelLabel}
|
|
13
|
+
id="cancel-btn">${props.options.cancelLabel}</button>
|
|
14
|
+
<button @click="${props._accept}" ?hidden=${!props.options
|
|
15
|
+
.acceptLabel} id="accept-btn" class="${ifDefined(props.options.type)}" >${
|
|
16
|
+
props.options.acceptLabel
|
|
17
|
+
}</button>
|
|
18
|
+
</div>
|
|
19
|
+
`;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const renderMessage = (options: ConfirmOptions) =>
|
|
23
|
+
html` <div id="message">${options.message || ""}</div> `;
|
|
24
|
+
|
|
25
|
+
function renderCustomContent(options: CustomConfirmOptions, props: DialogComponent) {
|
|
26
|
+
if (options.componentConstructor) {
|
|
27
|
+
const component = new options.componentConstructor() as LitElement;
|
|
28
|
+
component.setAttribute("id", "__custom-element__");
|
|
29
|
+
component.addEventListener("closed", props.componentCloseRequest.bind(props));
|
|
30
|
+
return html`${component}`;
|
|
31
|
+
}
|
|
32
|
+
return nothing;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@customElement("dialog-component")
|
|
36
|
+
export class DialogComponent extends LitElement {
|
|
37
|
+
render() {
|
|
38
|
+
return html`
|
|
39
|
+
<div
|
|
40
|
+
class="modal"
|
|
41
|
+
@click=${(e) => e.target === this.modal && this.close(false)}
|
|
42
|
+
>
|
|
43
|
+
<div
|
|
44
|
+
class="dialog"
|
|
45
|
+
>
|
|
46
|
+
<div class="dialog__header ${this.options.type}">
|
|
47
|
+
<h2 part="title">${this.options.title || ""}</h2>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="dialog__content">
|
|
50
|
+
${
|
|
51
|
+
this.options.message
|
|
52
|
+
? renderMessage(this.options)
|
|
53
|
+
: renderCustomContent(this.options, this)
|
|
54
|
+
}
|
|
55
|
+
</div>
|
|
56
|
+
${renderActions(this)}
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static get styles() {
|
|
63
|
+
return css`
|
|
64
|
+
${unsafeCSS(styles)}
|
|
65
|
+
`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@property()
|
|
69
|
+
options: ConfirmOptions & CustomConfirmOptions;
|
|
70
|
+
|
|
71
|
+
@query(".modal")
|
|
72
|
+
modal: any;
|
|
73
|
+
|
|
74
|
+
_cancel(e) {
|
|
75
|
+
console.log("canceling modal");
|
|
76
|
+
this.close(false);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
_accept(e) {
|
|
80
|
+
console.log("accepting modal");
|
|
81
|
+
this.close(true);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
componentCloseRequest(e: CustomEvent) {
|
|
85
|
+
this.close(e.detail);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async close(result: boolean) {
|
|
89
|
+
if (result) {
|
|
90
|
+
const component = this.getCustomComponent();
|
|
91
|
+
if (component?.canAccept) {
|
|
92
|
+
const canAccept = await component.canAccept();
|
|
93
|
+
if (!canAccept) return;
|
|
94
|
+
if (component.accept) await component.accept();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
this.modal.style.display = "none";
|
|
98
|
+
this.dispatchEvent(new CustomEvent("closed", { detail: result }));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
getCustomComponent(): IConfirmMixin | any {
|
|
102
|
+
return this.shadowRoot?.querySelector("#__custom-element__");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
@query("#accept-btn")
|
|
106
|
+
acceptButton: HTMLElement;
|
|
107
|
+
|
|
108
|
+
@query("#actions")
|
|
109
|
+
actionsContainer: HTMLElement;
|
|
110
|
+
|
|
111
|
+
@query("#header")
|
|
112
|
+
header: HTMLElement;
|
|
113
|
+
|
|
114
|
+
@query("#content")
|
|
115
|
+
content: HTMLElement;
|
|
116
|
+
|
|
117
|
+
show() {
|
|
118
|
+
this.modal.style.display = "block";
|
|
119
|
+
}
|
|
120
|
+
}
|
package/src/UI/shared-components/primaria-interaction/components/notifier-component-styles.scss
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
.snackbar {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
flex-direction: row;
|
|
5
|
+
justify-content: space-between;
|
|
6
|
+
gap: 10px;
|
|
7
|
+
visibility: hidden; /* Hidden by default. Visible on click */
|
|
8
|
+
min-width: 250px; /* Set a default minimum width */
|
|
9
|
+
width: 417px;
|
|
10
|
+
height: 56px;
|
|
11
|
+
background-color: #333;
|
|
12
|
+
color: #fff;
|
|
13
|
+
text-align: center;
|
|
14
|
+
border-radius: 10px;
|
|
15
|
+
font-weight: 500;
|
|
16
|
+
padding: 12px 16px;
|
|
17
|
+
position: fixed;
|
|
18
|
+
z-index: 500;
|
|
19
|
+
left: 24px;
|
|
20
|
+
box-shadow:
|
|
21
|
+
0 0px 2px rgba(0, 0, 0, 0.16),
|
|
22
|
+
0 0px 5px rgba(0, 0, 0, 0.23);
|
|
23
|
+
border: 2px solid;
|
|
24
|
+
border-color: transparent;
|
|
25
|
+
|
|
26
|
+
&__message {
|
|
27
|
+
text-align: left;
|
|
28
|
+
margin-right: 24px;
|
|
29
|
+
flex: 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&.show {
|
|
33
|
+
visibility: visible; /* Show the snackbar */
|
|
34
|
+
}
|
|
35
|
+
&.success {
|
|
36
|
+
background-color: #00893d;
|
|
37
|
+
color: white;
|
|
38
|
+
box-shadow:
|
|
39
|
+
rgb(67 160 71 / 30%) 0px 0px 2px,
|
|
40
|
+
rgb(67 160 71 / 22%) 0px 0px 5px;
|
|
41
|
+
}
|
|
42
|
+
&.danger {
|
|
43
|
+
background-color: red;
|
|
44
|
+
color: white;
|
|
45
|
+
box-shadow:
|
|
46
|
+
rgb(229 57 53 / 30%) 0px 0px 2px,
|
|
47
|
+
rgb(229 57 53 / 22%) 0px 0px 5px;
|
|
48
|
+
}
|
|
49
|
+
&.warning {
|
|
50
|
+
background-color: orange;
|
|
51
|
+
color: white;
|
|
52
|
+
box-shadow:
|
|
53
|
+
rgb(251 140 0 / 30%) 0px 0px 2px,
|
|
54
|
+
rgb(251 140 0 / 22%) 0px 0px 5px;
|
|
55
|
+
}
|
|
56
|
+
&.info {
|
|
57
|
+
background-color: blue;
|
|
58
|
+
color: white;
|
|
59
|
+
box-shadow:
|
|
60
|
+
rgb(14 80 138 / 30%) 0px 0px 2px,
|
|
61
|
+
rgb(14 80 138 / 22%) 0px 0px 5px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
$baseBottom: 72px;
|
|
65
|
+
$increment: 60px;
|
|
66
|
+
|
|
67
|
+
@for $i from 1 through 10 {
|
|
68
|
+
$bottom: $baseBottom + ($increment * ($i - 1));
|
|
69
|
+
|
|
70
|
+
/* Animations to fade the snackbar in and out */
|
|
71
|
+
@-webkit-keyframes fadein {
|
|
72
|
+
from {
|
|
73
|
+
bottom: 0;
|
|
74
|
+
opacity: 0;
|
|
75
|
+
}
|
|
76
|
+
to {
|
|
77
|
+
opacity: 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@keyframes fadein {
|
|
82
|
+
from {
|
|
83
|
+
bottom: 0;
|
|
84
|
+
opacity: 0;
|
|
85
|
+
}
|
|
86
|
+
to {
|
|
87
|
+
opacity: 1;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@-webkit-keyframes fadeout {
|
|
92
|
+
from {
|
|
93
|
+
opacity: 1;
|
|
94
|
+
}
|
|
95
|
+
to {
|
|
96
|
+
bottom: 0;
|
|
97
|
+
opacity: 0;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@keyframes fadeout {
|
|
102
|
+
from {
|
|
103
|
+
opacity: 1;
|
|
104
|
+
}
|
|
105
|
+
to {
|
|
106
|
+
bottom: 0;
|
|
107
|
+
opacity: 0;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&.notification-#{$i} {
|
|
112
|
+
-webkit-animation:
|
|
113
|
+
fadein 0.3s,
|
|
114
|
+
fadeout 0.55s 6s;
|
|
115
|
+
animation:
|
|
116
|
+
fadein 0.3s,
|
|
117
|
+
fadeout 0.55s 6s;
|
|
118
|
+
bottom: $bottom;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
#close-btn {
|
|
123
|
+
cursor: pointer;
|
|
124
|
+
}
|
|
125
|
+
span.dss-icon {
|
|
126
|
+
color: white;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { LitElement, css, html, unsafeCSS } from "lit";
|
|
2
|
+
import { customElement, property, query } from "lit/decorators.js";
|
|
3
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
4
|
+
import { NotifyOptions, NotifyType } from "../typings";
|
|
5
|
+
import styles from "./notifier-component-styles.scss?inline";
|
|
6
|
+
|
|
7
|
+
function getIcon(type: NotifyType | undefined) {
|
|
8
|
+
if (!type) return;
|
|
9
|
+
|
|
10
|
+
const types = new Map<NotifyType, string>([
|
|
11
|
+
["danger", "cancel"],
|
|
12
|
+
["info", "info"],
|
|
13
|
+
["warning", "warning"],
|
|
14
|
+
["success", "done"],
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
return types.get(type) as string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@customElement("notifier-component")
|
|
21
|
+
export class NotifierComponent extends LitElement {
|
|
22
|
+
render() {
|
|
23
|
+
return html`
|
|
24
|
+
<div class="snackbar ${this.options.type}">
|
|
25
|
+
<i class="dss-icon-button dss-icon-button--primary dss-icon-button--md ">
|
|
26
|
+
<span class="dss-icon">${ifDefined(getIcon(this.options.type))}</span>
|
|
27
|
+
</i>
|
|
28
|
+
<div class="snackbar__message">${this.options.message ?? ""}</div>
|
|
29
|
+
<div class="snackbar__action">
|
|
30
|
+
<dss-container><button class="dss-icon-button dss-icon-button--success dss-icon-button--md">
|
|
31
|
+
<span class="dss-icon" @click="${this.close}">close</span>
|
|
32
|
+
</button></dss-container>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static get styles() {
|
|
39
|
+
return css`
|
|
40
|
+
${unsafeCSS(styles)}
|
|
41
|
+
`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@property({ type: Object })
|
|
45
|
+
options: NotifyOptions;
|
|
46
|
+
|
|
47
|
+
@query(".snackbar")
|
|
48
|
+
snackbar: HTMLElement;
|
|
49
|
+
|
|
50
|
+
show() {
|
|
51
|
+
this.snackbar.classList.add("show");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
clearAndUpdateOrder(order: string) {
|
|
55
|
+
const classListValues = this.snackbar.classList.values();
|
|
56
|
+
|
|
57
|
+
for (const singleClass of classListValues) {
|
|
58
|
+
if (!singleClass.startsWith("notification")) continue;
|
|
59
|
+
|
|
60
|
+
this.snackbar.classList.remove(singleClass);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
this.snackbar.classList.add(order);
|
|
64
|
+
|
|
65
|
+
this.requestUpdate();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
close() {
|
|
69
|
+
this.snackbar.classList.remove("show");
|
|
70
|
+
|
|
71
|
+
this.dispatchEvent(new CustomEvent("closed"));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { dedupeMixin } from "@uxland/lit-utilities";
|
|
2
|
+
import { LitElement } from "lit";
|
|
3
|
+
import { property } from "lit/decorators.js";
|
|
4
|
+
import { Constructor } from "./typings";
|
|
5
|
+
|
|
6
|
+
export interface IConfirmMixin {
|
|
7
|
+
model: any;
|
|
8
|
+
close(result: boolean): void;
|
|
9
|
+
canAccept(): Promise<boolean> | boolean;
|
|
10
|
+
accept(): Promise<void> | void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export declare class ConfirmMixinBase {
|
|
14
|
+
model: any;
|
|
15
|
+
close(result: boolean): void;
|
|
16
|
+
canAccept(): Promise<boolean> | boolean;
|
|
17
|
+
accept(): Promise<void> | void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const ConfirmMixin = dedupeMixin(<T extends Constructor<LitElement>>(superClass: T) => {
|
|
21
|
+
class ConfirmMixinClass extends superClass implements ConfirmMixinBase {
|
|
22
|
+
@property()
|
|
23
|
+
model: T;
|
|
24
|
+
close(result: boolean) {
|
|
25
|
+
(this as any).dispatchEvent(new CustomEvent("closed", { detail: result }));
|
|
26
|
+
}
|
|
27
|
+
canAccept(): Promise<boolean> | boolean {
|
|
28
|
+
return Promise.resolve(true);
|
|
29
|
+
}
|
|
30
|
+
accept(): Promise<void> | void {
|
|
31
|
+
return Promise.resolve();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return ConfirmMixinClass as Constructor<ConfirmMixinBase> & T;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export function confirmMixin<T extends Constructor<LitElement>>(superClass: T) {
|
|
38
|
+
return ConfirmMixin(superClass as any) as unknown as Constructor<ConfirmMixinBase> & T;
|
|
39
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import "./components/dialog-component";
|
|
2
|
+
import { ConfirmOptions, CustomConfirmOptions } from "./typings";
|
|
3
|
+
|
|
4
|
+
export const doConfirm = async (
|
|
5
|
+
options: (ConfirmOptions & CustomConfirmOptions) | any,
|
|
6
|
+
): Promise<any> => {
|
|
7
|
+
if (!options.message && !options.componentConstructor) {
|
|
8
|
+
throw new Error("message, componentConstructor options properties are required");
|
|
9
|
+
}
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
const component: any = document.body.appendChild(document.createElement("dialog-component"));
|
|
12
|
+
|
|
13
|
+
component.options = options;
|
|
14
|
+
const result = component.updateComplete;
|
|
15
|
+
|
|
16
|
+
result.then(() => {
|
|
17
|
+
if (options.componentConstructor) {
|
|
18
|
+
const customComponent = component.shadowRoot.querySelector(`#__custom-element__`);
|
|
19
|
+
customComponent.model = options.model;
|
|
20
|
+
}
|
|
21
|
+
component.addEventListener("closed", closeComponent);
|
|
22
|
+
component.options && component.show();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
function closeComponent(e: { detail: any }) {
|
|
26
|
+
component.remove();
|
|
27
|
+
resolve(e.detail);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import "./components/notifier-component";
|
|
2
|
+
import { NotifierComponent } from "./components/notifier-component";
|
|
3
|
+
import { NotifyOptions } from "./typings";
|
|
4
|
+
|
|
5
|
+
function rand(c: "x" | "y") {
|
|
6
|
+
const r = (Math.random() * 16) | 0;
|
|
7
|
+
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
8
|
+
return v.toString(16);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function generateId() {
|
|
12
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, rand);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type NotifyOptionsWithId = NotifyOptions & { id: string };
|
|
16
|
+
|
|
17
|
+
const notificationStack: NotifyOptionsWithId[] = [];
|
|
18
|
+
|
|
19
|
+
const displayNotifications: NotifyOptionsWithId[] = [];
|
|
20
|
+
|
|
21
|
+
const stackLimit = 10;
|
|
22
|
+
|
|
23
|
+
const timeToCloseNotification = 5;
|
|
24
|
+
|
|
25
|
+
const updateNotificationOptsOrder = () => {
|
|
26
|
+
for (const [idx, notification] of displayNotifications.entries()) {
|
|
27
|
+
notification.order = `notification-${idx + 1}`;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const getComponentById = (id: string | undefined) =>
|
|
32
|
+
id ? (document.getElementById(id) as NotifierComponent | undefined) : undefined;
|
|
33
|
+
|
|
34
|
+
const showAndSetTimeOutClose = (component: NotifierComponent, timeInSeconds: number) => {
|
|
35
|
+
if (!getComponentById(component.id)) return;
|
|
36
|
+
|
|
37
|
+
component.show();
|
|
38
|
+
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
component.close();
|
|
41
|
+
}, timeInSeconds * 1000);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const removeCurrentComponent = (id: string) => {
|
|
45
|
+
const currentComponentIdx = displayNotifications.findIndex((n) => n.id === id);
|
|
46
|
+
|
|
47
|
+
const currentComponent = getComponentById(displayNotifications[currentComponentIdx]?.id);
|
|
48
|
+
|
|
49
|
+
if (!currentComponent) return;
|
|
50
|
+
|
|
51
|
+
currentComponent.remove();
|
|
52
|
+
|
|
53
|
+
displayNotifications.splice(currentComponentIdx, 1);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const removeFromStackAndAddToDisplay = () => {
|
|
57
|
+
const nextNotificationOpts = notificationStack[0];
|
|
58
|
+
|
|
59
|
+
const nextNotificationIsVisible =
|
|
60
|
+
nextNotificationOpts && displayNotifications.find((n) => n.id === nextNotificationOpts.id);
|
|
61
|
+
|
|
62
|
+
if (nextNotificationOpts && !nextNotificationIsVisible) {
|
|
63
|
+
displayNotifications.push(nextNotificationOpts);
|
|
64
|
+
|
|
65
|
+
notificationStack.shift();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const refreshAllComponentsOrder = () => {
|
|
70
|
+
for (const notification of displayNotifications) {
|
|
71
|
+
if (!notification.order) continue;
|
|
72
|
+
|
|
73
|
+
const notificationComponent = getComponentById(notification.id);
|
|
74
|
+
|
|
75
|
+
if (!notificationComponent) continue;
|
|
76
|
+
|
|
77
|
+
notificationComponent.clearAndUpdateOrder(notification.order);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const setNewDisplayNotification = () => {
|
|
82
|
+
const lastNotificationIdx = displayNotifications.length - 1;
|
|
83
|
+
|
|
84
|
+
const lastDisplayNotification = displayNotifications[lastNotificationIdx];
|
|
85
|
+
|
|
86
|
+
if (!lastDisplayNotification) return;
|
|
87
|
+
|
|
88
|
+
const lastComponent = getComponentById(lastDisplayNotification.id);
|
|
89
|
+
|
|
90
|
+
if (!lastComponent) return;
|
|
91
|
+
|
|
92
|
+
showAndSetTimeOutClose(lastComponent, timeToCloseNotification);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const closeAndUpdateStack = (id: string) => {
|
|
96
|
+
removeCurrentComponent(id);
|
|
97
|
+
|
|
98
|
+
removeFromStackAndAddToDisplay();
|
|
99
|
+
|
|
100
|
+
updateNotificationOptsOrder();
|
|
101
|
+
|
|
102
|
+
refreshAllComponentsOrder();
|
|
103
|
+
|
|
104
|
+
setNewDisplayNotification();
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const createNotifyComponent = (options: NotifyOptions, id: string) => {
|
|
108
|
+
const notifierComponentName = "notifier-component";
|
|
109
|
+
|
|
110
|
+
const component = document.body.appendChild(
|
|
111
|
+
document.createElement(notifierComponentName),
|
|
112
|
+
) as NotifierComponent;
|
|
113
|
+
|
|
114
|
+
component.options = options;
|
|
115
|
+
|
|
116
|
+
component.id = id;
|
|
117
|
+
|
|
118
|
+
return component;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const notify = (options: NotifyOptions) => {
|
|
122
|
+
const id = `${generateId()}`;
|
|
123
|
+
|
|
124
|
+
const optionWithId = { ...options, id };
|
|
125
|
+
|
|
126
|
+
if (displayNotifications.length < stackLimit) {
|
|
127
|
+
displayNotifications.push(optionWithId);
|
|
128
|
+
} else {
|
|
129
|
+
notificationStack.push(optionWithId);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!options.message) throw new Error("message is required");
|
|
133
|
+
|
|
134
|
+
const component = createNotifyComponent(options, id);
|
|
135
|
+
|
|
136
|
+
component.addEventListener("closed", () => closeAndUpdateStack(id));
|
|
137
|
+
|
|
138
|
+
const componentIsReady = component.updateComplete;
|
|
139
|
+
|
|
140
|
+
componentIsReady.then(() => {
|
|
141
|
+
if (!notificationStack.length && displayNotifications.length <= stackLimit) {
|
|
142
|
+
updateNotificationOptsOrder();
|
|
143
|
+
|
|
144
|
+
const order = displayNotifications.find((n) => n.id === id)?.order;
|
|
145
|
+
|
|
146
|
+
if (!order) return;
|
|
147
|
+
|
|
148
|
+
component.clearAndUpdateOrder(order);
|
|
149
|
+
|
|
150
|
+
showAndSetTimeOutClose(component, timeToCloseNotification);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
export declare type Constructor<T = Record<string, unknown>> = new (...args: any[]) => T;
|
|
3
|
+
|
|
4
|
+
export interface ConfirmOptions {
|
|
5
|
+
title: string;
|
|
6
|
+
message: string;
|
|
7
|
+
type: ConfirmType;
|
|
8
|
+
acceptLabel: string;
|
|
9
|
+
cancelLabel: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CustomConfirmOptions<T = any> {
|
|
13
|
+
title: string;
|
|
14
|
+
componentConstructor: Constructor<LitElement | any>;
|
|
15
|
+
type: ConfirmType;
|
|
16
|
+
acceptLabel?: string;
|
|
17
|
+
cancelLabel?: string;
|
|
18
|
+
model?: T;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type ConfirmType = "danger" | "warning" | "info" | "success";
|
|
22
|
+
|
|
23
|
+
export interface NotifyOptions {
|
|
24
|
+
message?: string;
|
|
25
|
+
type?: NotifyType;
|
|
26
|
+
position?: NotifyPosition;
|
|
27
|
+
order?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type NotifyOrder = "first" | "second" | "third" | "fourth" | "fifth";
|
|
31
|
+
export type NotifyPosition = "bottom" | "center" | "top";
|
|
32
|
+
export type NotifyType = "danger" | "warning" | "info" | "success" | "error";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { LitElement, html, css, unsafeCSS } from "lit";
|
|
2
|
+
import { template } from "./template";
|
|
3
|
+
import styles from "./styles.scss?inline";
|
|
4
|
+
import { customElement } from "lit/decorators.js";
|
|
5
|
+
|
|
6
|
+
@customElement("primaria-menu-item")
|
|
7
|
+
export class PrimariaMenuItem extends LitElement {
|
|
8
|
+
constructor(icon: string, label: string, callbackFn: () => void) {
|
|
9
|
+
super();
|
|
10
|
+
this.icon = icon;
|
|
11
|
+
this.label = label;
|
|
12
|
+
this.callbackFn = callbackFn;
|
|
13
|
+
}
|
|
14
|
+
render() {
|
|
15
|
+
return html`${template(this)}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static styles = css`
|
|
19
|
+
${unsafeCSS(styles)}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
icon: string;
|
|
23
|
+
label: string;
|
|
24
|
+
callbackFn: () => void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import { PrimariaMenuItem } from "./primaria-menu-item";
|
|
3
|
+
|
|
4
|
+
export const template = (props: PrimariaMenuItem) => html`
|
|
5
|
+
<div class="item" @click=${props.callbackFn}>
|
|
6
|
+
<dss-container><i class="dss-icon dss-icon--md">${props.icon}</i></dss-container>
|
|
7
|
+
<span>${props.label}</span>
|
|
8
|
+
</div>`;
|