adminforth 1.2.79 → 1.2.81

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.
@@ -1,4 +1,4 @@
1
- import { transformObject, deepMerge, createRGBA, parseColorForAliases, darkenRGBA, lightenRGBA } from "./utils.js";
1
+ import { transformObject, deepMerge, createRGBA, parseColorForAliases, darkenRGBA, lightenRGBA, inverseRGBA } from "./utils.js";
2
2
  import { styles } from "./styles.js";
3
3
  export class StylesGenerator {
4
4
  constructor(styleConfig) {
@@ -15,7 +15,7 @@ export class StylesGenerator {
15
15
  return plainCustomStyles;
16
16
  }
17
17
  changeAlias(str, mergedStyles) {
18
- const { aliasMatch, opacityMatch, darkenMatch, lightenMatch } = parseColorForAliases(str);
18
+ const { aliasMatch, opacityMatch, darkenMatch, lightenMatch, inverseMatch } = parseColorForAliases(str);
19
19
  if (!aliasMatch) {
20
20
  return str;
21
21
  }
@@ -29,6 +29,9 @@ export class StylesGenerator {
29
29
  if (lightenMatch) {
30
30
  return lightenRGBA(createRGBA(color, opacity));
31
31
  }
32
+ if (inverseMatch) {
33
+ return inverseRGBA(createRGBA(color, opacity));
34
+ }
32
35
  return createRGBA(color, opacity);
33
36
  }
34
37
  }
@@ -2,6 +2,7 @@ export const styles = () => ({
2
2
  colors: {
3
3
  lightHtml: "#FFFFFF", // main background
4
4
  lightPrimary: "#1a56db", // primary color
5
+ lightPrimaryContrast: "alias:lightPrimary inverse", // primary color contrast
5
6
  lightPrimaryOpacity: "alias:lightPrimary opacity:0.05", // primary color opacity
6
7
  lightNavbar: "#FFFFFF", // navbar background
7
8
  lightNavbarBorder: "rgb(229 231 235)", // border
@@ -9,6 +10,8 @@ export const styles = () => ({
9
10
  lightNavbarTextHover: "alias:lightNavbarText darken", // navbar text hover
10
11
  lightNavbarTextActive: "alias:lightNavbarText darken", // navbar text active
11
12
  lightNavbarIcons: "alias:lightNavbarText opacity:0.7", // navbar icons
13
+ lightAnnouncementText: "alias:lightPrimaryContrast", // announcement text
14
+ lightAnnouncementBG: "alias:lightPrimary", // announcement
12
15
  lightSidebar: "#f9fafb", // sidebar background
13
16
  lightSidebarBorder: "alias:lightSidebarText opacity:0.05", // sidebar right border
14
17
  lightSidebarItemHover: "alias:lightSidebarText opacity:0.05", // sidebar list item hover
@@ -51,6 +54,7 @@ export const styles = () => ({
51
54
  // colors for dark theme
52
55
  darkHtml: "#111827",
53
56
  darkPrimary: "#1c64f2", // primary color
57
+ darkPrimaryContrast: "alias:darkPrimary inverse", // primary color contrast
54
58
  darkPrimaryOpacity: "alias:darkPrimary opacity:0.1", // primary color opacity
55
59
  darkNavbar: "#111827",
56
60
  darkNavbarBorder: "#e5e7eb",
@@ -58,6 +62,8 @@ export const styles = () => ({
58
62
  darkNavbarTextHover: "alias:darkNavbarText lighten",
59
63
  darkNavbarTextActive: "alias:darkNavbarText lighten",
60
64
  darkNavbarIcons: "alias:darkNavbarText opacity:0.7",
65
+ darkAnnouncementText: "alias:darkPrimaryContrast",
66
+ darkAnnouncementBG: "alias:darkPrimary",
61
67
  darkSidebar: "#1f2937",
62
68
  darkSidebarBorder: "alias:darkSidebarText opacity:0.3",
63
69
  darkSidebarItemHover: "alias:darkSidebarText opacity:0.1",
@@ -266,12 +266,14 @@ export function parseColorForAliases(str) {
266
266
  const opacityRegex = /opacity:([0-9.]+)/;
267
267
  const darkenRegex = /darken/;
268
268
  const lightenRegex = /lighten/;
269
+ const inverseRegex = /inverse/;
269
270
  // Extract alias and properties
270
271
  const aliasMatch = str.match(aliasRegex);
271
272
  const opacityMatch = str.match(opacityRegex);
272
273
  const darkenMatch = str.match(darkenRegex);
273
274
  const lightenMatch = str.match(lightenRegex);
274
- return { aliasMatch, opacityMatch, darkenMatch, lightenMatch };
275
+ const inverseMatch = str.match(inverseRegex);
276
+ return { aliasMatch, opacityMatch, darkenMatch, lightenMatch, inverseMatch };
275
277
  }
276
278
  export function darkenRGBA(rgba) {
277
279
  let amount = 0.2;
@@ -299,3 +301,9 @@ export function lightenRGBA(rgba) {
299
301
  // Return the new RGBA color
300
302
  return `rgba(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}, ${a})`;
301
303
  }
304
+ export function inverseRGBA(rgba) {
305
+ // return white or black depending on the brightness of the color
306
+ let [r, g, b] = rgba.match(/\d+/g).map(Number);
307
+ let brightness = (r * 299 + g * 587 + b * 114) / 1000;
308
+ return brightness > 128 ? 'rgba(0,0,0,1)' : 'rgba(255,255,255,1)';
309
+ }
@@ -1,4 +1,4 @@
1
- import { transformObject,deepMerge,createRGBA,parseColorForAliases,darkenRGBA, lightenRGBA } from "./utils.js";
1
+ import { transformObject,deepMerge,createRGBA,parseColorForAliases,darkenRGBA, lightenRGBA, inverseRGBA } from "./utils.js";
2
2
  import { styles } from "./styles.js";
3
3
 
4
4
 
@@ -23,7 +23,7 @@ export class StylesGenerator {
23
23
  }
24
24
 
25
25
  private changeAlias(str:any, mergedStyles:any){
26
- const {aliasMatch,opacityMatch,darkenMatch,lightenMatch} = parseColorForAliases(str);
26
+ const {aliasMatch,opacityMatch,darkenMatch,lightenMatch, inverseMatch} = parseColorForAliases(str);
27
27
  if (!aliasMatch) {
28
28
  return str;
29
29
  } else {
@@ -33,9 +33,12 @@ export class StylesGenerator {
33
33
  if (darkenMatch) {
34
34
  return darkenRGBA(createRGBA(color, opacity))
35
35
  }
36
- if (lightenMatch){
36
+ if (lightenMatch){
37
37
  return lightenRGBA(createRGBA(color, opacity))
38
38
  }
39
+ if (inverseMatch){
40
+ return inverseRGBA(createRGBA(color, opacity))
41
+ }
39
42
  return createRGBA(color, opacity);
40
43
  }
41
44
  }
package/modules/styles.ts CHANGED
@@ -5,6 +5,7 @@ export const styles = () => ({
5
5
  lightHtml: "#FFFFFF", // main background
6
6
 
7
7
  lightPrimary: "#1a56db", // primary color
8
+ lightPrimaryContrast: "alias:lightPrimary inverse", // primary color contrast
8
9
  lightPrimaryOpacity: "alias:lightPrimary opacity:0.05", // primary color opacity
9
10
 
10
11
  lightNavbar: "#FFFFFF", // navbar background
@@ -13,6 +14,8 @@ export const styles = () => ({
13
14
  lightNavbarTextHover: "alias:lightNavbarText darken", // navbar text hover
14
15
  lightNavbarTextActive: "alias:lightNavbarText darken", // navbar text active
15
16
  lightNavbarIcons: "alias:lightNavbarText opacity:0.7", // navbar icons
17
+ lightAnnouncementText: "alias:lightPrimaryContrast", // announcement text
18
+ lightAnnouncementBG: "alias:lightPrimary", // announcement
16
19
 
17
20
  lightSidebar: "#f9fafb", // sidebar background
18
21
  lightSidebarBorder: "alias:lightSidebarText opacity:0.05", // sidebar right border
@@ -63,6 +66,7 @@ export const styles = () => ({
63
66
  darkHtml: "#111827",
64
67
 
65
68
  darkPrimary: "#1c64f2", // primary color
69
+ darkPrimaryContrast: "alias:darkPrimary inverse", // primary color contrast
66
70
  darkPrimaryOpacity: "alias:darkPrimary opacity:0.1", // primary color opacity
67
71
 
68
72
  darkNavbar: "#111827",
@@ -71,6 +75,8 @@ export const styles = () => ({
71
75
  darkNavbarTextHover: "alias:darkNavbarText lighten",
72
76
  darkNavbarTextActive: "alias:darkNavbarText lighten",
73
77
  darkNavbarIcons: "alias:darkNavbarText opacity:0.7",
78
+ darkAnnouncementText: "alias:darkPrimaryContrast",
79
+ darkAnnouncementBG: "alias:darkPrimary",
74
80
 
75
81
  darkSidebar: "#1f2937",
76
82
  darkSidebarBorder: "alias:darkSidebarText opacity:0.3",
package/modules/utils.ts CHANGED
@@ -282,13 +282,15 @@ export function parseColorForAliases(str){
282
282
  const opacityRegex = /opacity:([0-9.]+)/;
283
283
  const darkenRegex = /darken/;
284
284
  const lightenRegex = /lighten/;
285
+ const inverseRegex = /inverse/;
285
286
 
286
287
  // Extract alias and properties
287
288
  const aliasMatch = str.match(aliasRegex);
288
289
  const opacityMatch = str.match(opacityRegex)
289
290
  const darkenMatch = str.match(darkenRegex)
290
291
  const lightenMatch = str.match(lightenRegex)
291
- return {aliasMatch,opacityMatch,darkenMatch,lightenMatch}
292
+ const inverseMatch = str.match(inverseRegex)
293
+ return {aliasMatch,opacityMatch,darkenMatch,lightenMatch, inverseMatch}
292
294
  }
293
295
 
294
296
  export function darkenRGBA(rgba) {
@@ -326,4 +328,10 @@ export function lightenRGBA(rgba) {
326
328
  }
327
329
 
328
330
 
331
+ export function inverseRGBA(rgba) {
332
+ // return white or black depending on the brightness of the color
333
+ let [r, g, b] = rgba.match(/\d+/g).map(Number);
334
+ let brightness = (r * 299 + g * 587 + b * 114) / 1000;
335
+ return brightness > 128 ? 'rgba(0,0,0,1)' : 'rgba(255,255,255,1)';
336
+ }
329
337
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "1.2.79",
3
+ "version": "1.2.81",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/spa/src/App.vue CHANGED
@@ -107,17 +107,20 @@
107
107
  </ul>
108
108
 
109
109
 
110
- <div id="dropdown-cta" class="p-4 mt-6 rounded-lg bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity" role="alert"
110
+ <div id="dropdown-cta" class="p-4 mt-6 rounded-lg bg-lightAnnouncementBG dark:bg-darkAnnouncementBG
111
+ fill-lightAnnouncementText dark:fill-darkAccent text-lightAnnouncementText dark:text-darkAccent text-sm
112
+ " role="alert"
111
113
  v-if="ctaBadge"
112
114
  >
113
115
  <div class="flex items-center mb-3">
114
- <span class="bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity text-lightNavbarText dark:text-darkNavbarPrimary text-sm font-semibold me-2 px-2.5 py-0.5 rounded "
116
+ <!-- <span class="bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity text-sm font-semibold me-2 px-2.5 py-0.5 rounded "
115
117
  v-if="ctaBadge.title"
116
- >
118
+ > -->
119
+ <span>
117
120
  {{ctaBadge.title}}
118
121
  </span>
119
122
  <button type="button"
120
- class="ms-auto -mx-1.5 -my-1.5 bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity inline-flex justify-center items-center w-6 h-6 text-lightNavbarText dark:text-darkNavbarText rounded-lg focus:ring-2 focus:ring-blue-400 p-1 hover:bg-blue-200 dark:bg-blue-900 dark:text-blue-400 dark:hover:bg-blue-800"
123
+ class="ms-auto -mx-1.5 -my-1.5 bg-lightPrimaryOpacity dark:bg-darkPrimaryOpacity inline-flex justify-center items-center w-6 h-6 rounded-lg p-1 hover:brightness-110"
121
124
  data-dismiss-target="#dropdown-cta" aria-label="Close"
122
125
  v-if="ctaBadge?.closable" @click="closeCTA"
123
126
  >
@@ -127,7 +130,7 @@
127
130
  </svg>
128
131
  </button>
129
132
  </div>
130
- <p class="mb-3 text-sm fill-lightNavbarText dark:fill-darkPrimary text-lightNavbarText dark:text-darkNavbarPrimary" v-if="ctaBadge.html" v-html="ctaBadge.html"></p>
133
+ <p class="mb-3 text-sm " v-if="ctaBadge.html" v-html="ctaBadge.html"></p>
131
134
  <p class="mb-3 text-sm fill-lightNavbarText dark:fill-darkPrimary text-lightNavbarText dark:text-darkNavbarPrimary" v-else>
132
135
  {{ ctaBadge.text }}
133
136
  </p>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div>
3
3
  <span @click="(e)=>{e.stopPropagation()}" v-if="column.foreignResource">
4
- <RouterLink v-if="record[column.name]" class="font-medium text-blue-600 dark:text-blue-500 hover:brightness-110"
4
+ <RouterLink v-if="record[column.name]" class="font-medium text-lightPrimary dark:text-darkPrimary hover:brightness-110"
5
5
  :to="{ name: 'resource-show', params: { resourceId: column.foreignResource.resourceId, primaryKey: record[column.name].pk } }">
6
6
  {{ record[column.name].label }}
7
7
  </RouterLink>
@@ -21,7 +21,7 @@
21
21
  {{ checkEmptyValues(formatDate(record[column.name]),route.meta.type) }}
22
22
  </span>
23
23
  <span v-else-if="column.type === 'richtext'">
24
- <div v-html="protectAgainstXSS(record[column.name])"></div>
24
+ <div v-html="protectAgainstXSS(record[column.name])" class="allow-lists"></div>
25
25
  </span>
26
26
  <span v-else>
27
27
  {{ checkEmptyValues(record[column.name],route.meta.type) }}
@@ -55,7 +55,11 @@ const props = defineProps({
55
55
  });
56
56
 
57
57
  function protectAgainstXSS(value) {
58
- return sanitizeHtml(value);
58
+ return sanitizeHtml(value, {
59
+ allowedAttributes: {
60
+ 'li': [ 'data-list' ],
61
+ }
62
+ });
59
63
  }
60
64
 
61
65
 
@@ -63,4 +67,22 @@ function formatDate(date) {
63
67
  if (!date) return '';
64
68
  return dayjs.utc(date).local().format(coreStore.config?.datesFormat || 'YYYY-MM-DD HH:mm:ss');
65
69
  }
66
- </script>
70
+ </script>
71
+
72
+ <style lang="scss">
73
+
74
+ .allow-lists {
75
+ ol {
76
+ list-style-type: decimal;
77
+ padding-left: 1.5em;
78
+
79
+ li[data-list="bullet"] {
80
+ list-style-type: disc;
81
+ }
82
+ li[data-list="ordered"] {
83
+ list-style-type: decimal;
84
+ }
85
+ }
86
+
87
+ }
88
+ </style>