@simple-reporting/base 1.0.7 → 1.0.9

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/dev/package.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "postinstall": "srl prepare"
20
20
  },
21
21
  "dependencies": {
22
- "@simple-reporting/base": "^1.0.7",
22
+ "@simple-reporting/base": "^1.0.9",
23
23
  "axios": "^1.9.0",
24
24
  "chalk": "^5.4.1",
25
25
  "exceljs": "^4.4.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simple-reporting/base",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Manage srl templates, build and publish",
5
5
  "bin": {
6
6
  "srl": "cli.js"
@@ -339,6 +339,13 @@ async function writeComponent(group, name) {
339
339
  return false;
340
340
  }
341
341
 
342
+ const componentNameArray = name.split('.');
343
+ let componentName = name;
344
+ if (componentNameArray[1]) {
345
+ componentNameArray.shift()
346
+ componentName = componentNameArray.join(('.'));
347
+ }
348
+
342
349
  try {
343
350
  const stat = await statSync(join(folders.ld, group, name));
344
351
  console.error(`Component ${group}/${name} already exist!`);
@@ -353,9 +360,9 @@ async function writeComponent(group, name) {
353
360
  await mkdirSync(join(folders.ld, group, name));
354
361
  await mkdirSync(join(folders.ld, group, name, 'scss'));
355
362
  await writeFileSync(
356
- join(folders.ld, group, name, `${name}.html`),
357
- `<p class="srl-grid srl-${name} srl-linkable">
358
- <span class="srl-grid__inner srl-${name}__text" doc-editable="paragraph">
363
+ join(folders.ld, group, name, `${componentName}.html`),
364
+ `<p class="srl-grid srl-${componentName} srl-linkable">
365
+ <span class="srl-grid__inner srl-${componentName}__text" doc-editable="paragraph">
359
366
  Editable Text
360
367
  </span>
361
368
  </p>
@@ -364,8 +371,8 @@ async function writeComponent(group, name) {
364
371
  await writeFileSync(
365
372
  join(folders.ld, group, name, `ld-conf.json`),
366
373
  `{
367
- "name": "${name}",
368
- "label": "${name.charAt(0).toUpperCase()}${name.slice(1)}"
374
+ "name": "${componentName}",
375
+ "label": "${componentName.charAt(0).toUpperCase()}${componentName.slice(1)}"
369
376
  }`,
370
377
  );
371
378
  await writeFileSync(
@@ -379,9 +386,9 @@ async function writeComponent(group, name) {
379
386
  await writeFileSync(
380
387
  join(folders.ld, group, name, 'scss', `general.scss`),
381
388
  `@use "srl";
382
- .srl-${name} {
383
-
384
- }`,
389
+ .srl-${componentName} {
390
+
391
+ }`,
385
392
  );
386
393
  await writeFileSync(
387
394
  join(folders.ld, group, name, 'scss', `pdf.scss`),
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ item: NsWowNavigationItem
4
+ }>();
5
+
6
+ const prefix = props.item.iconPrefix ?? 'srl-icon'
7
+ </script>
8
+
9
+ <template>
10
+ <i :class="`${prefix} ${prefix}-${props.item.icon}`" aria-hidden="true"></i>
11
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ item: NsWowNavigationItem;
4
+ }>();
5
+
6
+ const prefix = props.item.iconPrefix ?? 'srl-icon'
7
+ </script>
8
+
9
+ <template>
10
+ <span>{{ props.item.label }}</span>
11
+ <i :class="`${prefix} ${prefix}-${props.item.iconAfter}`" aria-hidden="true"></i>
12
+ </template>
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps<{
3
+ item: NsWowNavigationItem;
4
+ }>();
5
+
6
+ const prefix = props.item.iconPrefix ?? 'srl-icon'
7
+ </script>
8
+
9
+ <template>
10
+ <i :class="`${prefix} ${prefix}-${props.item.iconAfter}`" aria-hidden="true"></i>
11
+ <span>{{ props.item.label }}</span>
12
+ </template>
@@ -5,5 +5,5 @@ const pops = defineProps<{
5
5
  </script>
6
6
 
7
7
  <template>
8
- {{ pops.item.label }}
8
+ <span>{{ pops.item.label }}</span>
9
9
  </template>
@@ -3,6 +3,9 @@ import MenuItemContentText from './Content/Text.vue';
3
3
  import MenuItemContentImage from './Content/Image.vue';
4
4
  import MenuItemContentImageBefore from './Content/ImageBefore.vue';
5
5
  import MenuItemContentImageAfter from './Content/ImageAfter.vue';
6
+ import MenuItemContentIcon from './Content/Icon.vue';
7
+ import MenuItemContentIconBefore from './Content/IconBefore.vue';
8
+ import MenuItemContentIconAfter from './Content/IconAfter.vue';
6
9
 
7
10
  const props = defineProps<{
8
11
  item: NsWowNavigationItem;
@@ -10,7 +13,22 @@ const props = defineProps<{
10
13
  </script>
11
14
 
12
15
  <template>
13
- <MenuItemContentImage v-if="props.item.img" :item="props.item" />
16
+ <MenuItemContentIcon
17
+ v-if="props.item.icon"
18
+ :item="props.item"
19
+ />
20
+ <MenuItemContentIconBefore
21
+ v-else-if="props.item.iconBefore"
22
+ :item="props.item"
23
+ />
24
+ <MenuItemContentIconAfter
25
+ v-else-if="props.item.iconAfter"
26
+ :item="props.item"
27
+ />
28
+ <MenuItemContentImage
29
+ v-else-if="props.item.img"
30
+ :item="props.item"
31
+ />
14
32
  <MenuItemContentImageBefore
15
33
  v-else-if="props.item.imgBefore"
16
34
  :item="props.item"
@@ -66,6 +66,8 @@ function toggle() {
66
66
  const item = menu.value?.items[0].$el;
67
67
  item.$el ? item.$el.focus() : item.focus();
68
68
  });
69
+ } else {
70
+ menu.value.closeAll();
69
71
  }
70
72
  }
71
73
 
@@ -124,6 +126,16 @@ defineExpose({
124
126
  menu,
125
127
  });
126
128
 
129
+ function internalLinkClick(event: Event) {
130
+ !props.item.callback || props.item.callback(event);
131
+ routerChange()
132
+ }
133
+
134
+ function externalLinkClick(event: Event) {
135
+ !props.item.callback || props.item.callback(event);
136
+ link()
137
+ }
138
+
127
139
  const dynamicAttributes = computed(() => {
128
140
  return props.item.attributes ?? {};
129
141
  });
@@ -139,7 +151,7 @@ const dynamicAttributes = computed(() => {
139
151
  :class="{ active: item.active }"
140
152
  :title="props.item.title ?? props.item.label"
141
153
  v-bind="dynamicAttributes"
142
- @click="routerChange"
154
+ @click="internalLinkClick"
143
155
  @keydown.left.stop.prevent="prev"
144
156
  @keydown.up.stop.prevent="prev"
145
157
  @keydown.down.stop.prevent="next"
@@ -147,7 +159,6 @@ const dynamicAttributes = computed(() => {
147
159
  @keydown.tab.exact="tab"
148
160
  @keydown.shift.tab.exact="back"
149
161
  @keydown.esc.stop.prevent="close"
150
- @keydown.enter="link"
151
162
  >
152
163
  <MenuItemContent :item="props.item" />
153
164
  </router-link>
@@ -157,9 +168,10 @@ const dynamicAttributes = computed(() => {
157
168
  ref="$el"
158
169
  :href="props.item.href"
159
170
  :title="props.item.title ?? props.item.label"
171
+ :aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
160
172
  :target="props.item.href?.startsWith('http') ? '_blank' : undefined"
161
173
  v-bind="dynamicAttributes"
162
- @click="link"
174
+ @click="externalLinkClick"
163
175
  @keydown.left.stop.prevent="prev"
164
176
  @keydown.up.stop.prevent="prev"
165
177
  @keydown.down.stop.prevent="next"
@@ -177,6 +189,7 @@ const dynamicAttributes = computed(() => {
177
189
  ref="$el"
178
190
  :tabindex="props.index === 0 && !props.disableTabIndex ? 0 : -1"
179
191
  :title="props.item.title ?? props.item.label"
192
+ :aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
180
193
  v-bind="dynamicAttributes"
181
194
  @click="props.item.callback"
182
195
  @keydown.left.stop.prevent="prev"
@@ -199,8 +212,9 @@ const dynamicAttributes = computed(() => {
199
212
  :aria-expanded="opened"
200
213
  :aria-controls="`${props.name}-${id}`"
201
214
  :title="props.item.title ?? props.item.label"
215
+ :aria-label="props.item.icon ? props.item.title ?? props.item.label : undefined"
202
216
  v-bind="dynamicAttributes"
203
- @click="toggle"
217
+ @click.stop="toggle"
204
218
  @keydown.left.stop.prevent="prev"
205
219
  @keydown.up.stop.prevent="prev"
206
220
  @keydown.down.stop.prevent="next"
@@ -192,10 +192,7 @@ const menuItems = computed<NsWowNavigationItem[]>(() => {
192
192
  'aria-controls': props.id,
193
193
  'aria-expanded': opened.value
194
194
  },
195
- callback: () => {
196
- opened.value = false
197
- emit('back')
198
- },
195
+ callback: close,
199
196
  },
200
197
  ...props.menu,
201
198
  ] : props.menu
@@ -7,6 +7,7 @@ import _useMenu from './menu';
7
7
  import _useSearch from './search';
8
8
  import _useSettings from './settings';
9
9
  import _useViewPort from './viewPort';
10
+ import _useLanguageSwitch from './languageSwitch';
10
11
  import * as cssStyles from './cssStyles.ts'
11
12
 
12
13
  export const useArticle = _useArticle;
@@ -18,6 +19,7 @@ export const useMenu = _useMenu;
18
19
  export const useSearch = _useSearch;
19
20
  export const useSettings = _useSettings;
20
21
  export const useViewPort = _useViewPort;
22
+ export const useLanguageSwitch = _useLanguageSwitch;
21
23
  export const addCssStyles = cssStyles.addCssStyles;
22
24
  export const useCssStyles = cssStyles.useCssStyles;
23
25
 
@@ -31,6 +33,7 @@ export default {
31
33
  useSearch,
32
34
  useSettings,
33
35
  useViewPort,
36
+ useLanguageSwitch,
34
37
  addCssStyles,
35
38
  useCssStyles,
36
39
  };
@@ -0,0 +1,53 @@
1
+ import { computed } from 'vue'
2
+ import Tr from '@/i18n/translation.ts'
3
+ import { useArticle, useConfig } from '#composables'
4
+
5
+
6
+
7
+ type NsWowLanguageSwitch = {
8
+ current: { label: string; href: string },
9
+ items: NsWowNavigationItem[]
10
+ }
11
+
12
+ const languageSwitch = computed<NsWowLanguageSwitch>(() => {
13
+
14
+ const config = useConfig()
15
+ const article = useArticle()
16
+
17
+ const res: NsWowLanguageSwitch = {
18
+ current: { label: config.value.locale, href: `/${config.value.locale}` },
19
+ items: []
20
+ }
21
+ for (const locale of config.value.settings.languages) {
22
+ if (locale !== config.value.locale) {
23
+ res.items.push({
24
+ label: locale,
25
+ href: `/${locale}`,
26
+ callback: () => {
27
+ Tr.switchLanguage(locale)
28
+ }
29
+ })
30
+ }
31
+ }
32
+
33
+ if (article.value) {
34
+ const uuid = article.value.uuid
35
+ if (uuid) {
36
+ for (const locale of config.value.settings.languages) {
37
+ const slug = config.value.articles[locale].find((a) => a.uuid === uuid)?.slug || ''
38
+ if (locale === config.value.locale) {
39
+ res.current.href = `/${locale}/${slug}`
40
+ } else {
41
+ const item = res.items.find((i) => i.label === locale)
42
+ item ? item.href = `/${locale}/${slug}` : null
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ return res
49
+ })
50
+
51
+ export default function useLanguageSwitch() {
52
+ return languageSwitch
53
+ }
@@ -38,6 +38,7 @@
38
38
  */
39
39
  import { computed, type ComputedRef, ref } from 'vue';
40
40
  import { HTMLElement, parse as parseHtml } from 'node-html-parser';
41
+ import { useConfig, useArticles } from '#composables';
41
42
 
42
43
  const storage = ref<{
43
44
  [locale: string]: NsWowSearchList[];
@@ -68,7 +69,7 @@ function makeWords(html: string) {
68
69
  .replace(/\s{2,}/g, ' ');
69
70
  }
70
71
 
71
- export default async function useSearch(): ComputedRef<NsWowSearchList[]> {
72
+ export default async function useSearch(): Promise<ComputedRef<NsWowSearchList[]>> {
72
73
  const config = useConfig();
73
74
  if (!storage.value || !storage.value[config.value.locale]) {
74
75
  !storage.value ? (storage.value = {}) : null;
@@ -92,6 +92,9 @@ declare global {
92
92
  export type NsWowNavigationItem = {
93
93
  label: string;
94
94
  title?: string;
95
+ icon?: string;
96
+ iconBefore?: string;
97
+ iconAfter?: string;
95
98
  img?: {
96
99
  src: string;
97
100
  alt?: string;
package/srl/utils/html.ts CHANGED
@@ -7,6 +7,8 @@ function attributesToString(attributes: Record<string, string | null>): string {
7
7
  .join(' ');
8
8
  }
9
9
 
10
+ type AttrObj = { [key: string]: string | null };
11
+
10
12
  export function prepareHtmlContent(text: string): string {
11
13
  const articles = useArticles();
12
14
  const locale = useLocale();
@@ -14,8 +16,8 @@ export function prepareHtmlContent(text: string): string {
14
16
  const regex = /<a\s+([^>]+)>(.*?)<\/a>/gis;
15
17
  text = text.replace(regex, (match, attrString, innerText) => {
16
18
  // Attribute in ein Array umwandeln
17
- const attrObj = {};
18
- attrString.replace(/([a-zA-Z0-9\-_]+)(?:="([^"]*)")?/g, (m, key, value) => {
19
+ const attrObj: AttrObj = {};
20
+ attrString.replace(/([a-zA-Z0-9\-_]+)(?:="([^"]*)")?/g, (m, key: string, value: string | null) => {
19
21
  attrObj[key] = value || null;
20
22
  return m;
21
23
  });
@@ -66,6 +68,11 @@ export function prepareHtmlContent(text: string): string {
66
68
  return match;
67
69
  });
68
70
 
71
+ text = text.replace(
72
+ /<template-([a-z]+)>([\s\S]*?)<\/template-\1>/g,
73
+ (_match, name, content) => `<template #${name}>${content}</template>`
74
+ );
75
+
69
76
  text = text.replaceAll('../', `./`);
70
77
 
71
78
  text = text.replace(/<style[^>]*>([\s\S]*?)<\/style>/gi, (match, p1) => {