rimecms 0.26.2 → 0.26.4

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,5 +1,6 @@
1
1
  import { dev } from '$app/environment';
2
2
  import { RimeError, RimeFormError } from '../../../../errors/index.js';
3
+ import { t__ } from '../../../../i18n/index.js';
3
4
  import { Hooks } from '../../../../operations/hooks/index.server.js';
4
5
  import { access } from '../../../../../util/access/index.js';
5
6
  import { cases } from '../../../../../util/cases.js';
@@ -149,8 +150,8 @@ export const createBetterAuthUser = Hooks.beforeCreate(async (args) => {
149
150
  // Send api key by email to the user
150
151
  await rime.mailer.sendMail({
151
152
  to: event.locals.user.email,
152
- subject: 'Your API Key',
153
- text: `Your ${args.data.name} apiKey : ${apiKey}, keep it safe, only server-side`
153
+ subject: t__(`mail.api_key_created_subject`, args.data.name),
154
+ text: t__(`mail.api_key_created_text`, args.data.name, apiKey.key)
154
155
  });
155
156
  return {
156
157
  ...args,
@@ -0,0 +1,5 @@
1
+ declare namespace _default {
2
+ let api_key_created_subject: string;
3
+ let api_key_created_text: string;
4
+ }
5
+ export default _default;
@@ -0,0 +1,4 @@
1
+ export default {
2
+ api_key_created_subject: 'Your API Key',
3
+ api_key_created_text: `Your $1 apiKey : $2, keep it safe, only server-side`
4
+ };
@@ -0,0 +1,5 @@
1
+ declare namespace _default {
2
+ let api_key_created_subject: string;
3
+ let api_key_created_text: string;
4
+ }
5
+ export default _default;
@@ -0,0 +1,4 @@
1
+ export default {
2
+ api_key_created_subject: 'Votre clé API',
3
+ api_key_created_text: `Votre clé API $1 : $2, gardez-la en sécurité, uniquement côté serveur`
4
+ };
@@ -1,5 +1,5 @@
1
1
  export declare const languages: readonly ["fr", "en"];
2
- export declare const namespaces: readonly ["errors", "fields", "common"];
2
+ export declare const namespaces: readonly ["errors", "fields", "common", "mail"];
3
3
  export declare const DEFAULT_LOCALE = "en";
4
4
  export type PanelLanguage = (typeof languages)[number];
5
5
  export type Namespace = (typeof namespaces)[number];
@@ -1,5 +1,5 @@
1
1
  export const languages = ['fr', 'en'];
2
- export const namespaces = ['errors', 'fields', 'common'];
2
+ export const namespaces = ['errors', 'fields', 'common', 'mail'];
3
3
  export const DEFAULT_LOCALE = 'en';
4
4
  function createI18n() {
5
5
  let dictionaries = {};
@@ -5,12 +5,14 @@ const translationModules = {
5
5
  en: {
6
6
  common: () => import('./en/common.js'),
7
7
  errors: () => import('./en/errors.js'),
8
- fields: () => import('./en/fields.js')
8
+ fields: () => import('./en/fields.js'),
9
+ mail: () => import('./en/mail.js')
9
10
  },
10
11
  fr: {
11
12
  common: () => import('./fr/common.js'),
12
13
  errors: () => import('./fr/errors.js'),
13
- fields: () => import('./fr/fields.js')
14
+ fields: () => import('./fr/fields.js'),
15
+ mail: () => import('./fr/mail.js')
14
16
  }
15
17
  };
16
18
  export async function registerTranslation(locale) {
@@ -106,8 +106,8 @@
106
106
 
107
107
  {#if inputFocused}
108
108
  <Command.List>
109
- {#each availableItems as item (item.documentId)}
110
- <Command.Item value={item.title} onSelect={() => onSelect(item)}>
109
+ {#each availableItems as item, index (item.documentId)}
110
+ <Command.Item value="{item.title}-{index}" onSelect={() => onSelect(item)}>
111
111
  <span>{item.title}</span>
112
112
  </Command.Item>
113
113
  {/each}
@@ -155,8 +155,13 @@
155
155
  {/if}
156
156
  </div>
157
157
 
158
- <style>
159
- .rz-relation {
158
+ <style>/**************************************/
159
+
160
+ /* Font */
161
+
162
+ /**************************************/
163
+
164
+ .rz-relation {
160
165
  position: relative;
161
166
 
162
167
  :global {
@@ -54,10 +54,13 @@
54
54
  const user = getUserContext();
55
55
 
56
56
  let formElement = $state<HTMLFormElement>();
57
-
57
+ // This is used to intercept navigation when there are unsaved changes in the form
58
+ // It stores the URL the user is trying to navigate to, so we can redirect them there after they confirm they want to leave
58
59
  let interceptedLeave = $state<{ url: string } | null>(null);
60
+ // This is used to prevent the beforeNavigate from triggering when we programmatically navigate
59
61
  let isRedirect = $state(false);
60
62
 
63
+ // Intercept navigation when there are unsaved changes in the form
61
64
  beforeNavigate(async ({ cancel, to }) => {
62
65
  const hasCHanges = Object.keys(form.changes).length > 0;
63
66
  if (!hasCHanges) return;
@@ -108,6 +111,7 @@
108
111
  return new Promise<boolean>((resolve) => {
109
112
  function checkAndResolve() {
110
113
  if (!apiKey) {
114
+ isRedirect = !!data?.redirectUrl;
111
115
  resolve(true);
112
116
  clearInterval(intervalId);
113
117
  }
@@ -150,7 +154,8 @@
150
154
  <UploadHeader accept={config.upload.accept} create={operation === 'create'} {form} />
151
155
  {/if}
152
156
  <RenderFields fields={config.fields} {form} />
153
- {#if config.type === 'collection' && isAuthConfig(config)}
157
+ <!-- -->
158
+ {#if config.type === 'collection' && isAuthConfig(config) && config.auth.type === 'password'}
154
159
  <AuthFooter collection={config} {operation} {form} />
155
160
  {/if}
156
161
  </div>
@@ -192,13 +197,14 @@
192
197
  {t__('common.leave_confirm_title')}
193
198
  </Dialog.Header>
194
199
  <p>{t__('common.leave_confirm_text')}</p>
200
+ <!-- -->
195
201
  <Dialog.Footer --rz-justify-content="space-between">
196
- <Button onclick={() => interceptedLeave && goto(interceptedLeave.url)}
197
- >{t__('common.confirm')}</Button
198
- >
199
- <Button onclick={() => (interceptedLeave = null)} variant="secondary"
200
- >{t__('common.cancel')}</Button
201
- >
202
+ <Button onclick={() => interceptedLeave && goto(interceptedLeave.url)}>
203
+ {t__('common.confirm')}
204
+ </Button>
205
+ <Button onclick={() => (interceptedLeave = null)} variant="secondary">
206
+ {t__('common.cancel')}
207
+ </Button>
202
208
  </Dialog.Footer>
203
209
  </Dialog.Content>
204
210
  </Dialog.Root>
@@ -18,9 +18,11 @@
18
18
 
19
19
  const isUpload = $derived('mimeType' in resource);
20
20
  const isImage = $derived(
21
- resource._thumbnail || (isUpload && resource.mimeType!.includes('image'))
21
+ resource._thumbnail || (isUpload && resource.mimeType?.includes('image'))
22
+ );
23
+ const Icon = $derived(
24
+ isUpload && resource.mimeType ? mimeTypeToIcon(resource.mimeType) : FileIcon
22
25
  );
23
- const Icon = $derived(isUpload ? mimeTypeToIcon(resource.mimeType!) : FileIcon);
24
26
  </script>
25
27
 
26
28
  <div class="rz-card-resource">
@@ -51,14 +53,19 @@
51
53
  </button>
52
54
  </div>
53
55
 
54
- <style>
55
- :root {
56
+ <style>/**************************************/
57
+
58
+ /* Font */
59
+
60
+ /**************************************/
61
+
62
+ :root {
56
63
  --rz-ressource-card-bg: light-dark(hsl(var(--rz-gray-18)), hsl(var(--rz-gray-4)));
57
64
  --rz-ressource-card-thumbnail-bg: light-dark(hsl(var(--rz-gray-15)), hsl(var(--rz-gray-2)));
58
65
  --rz-border-radius: var(--rz-radius-md);
59
66
  }
60
67
 
61
- .rz-card-resource {
68
+ .rz-card-resource {
62
69
  --padding: var(--rz-card-padding, var(--rz-size-2));
63
70
  --rz-size: var(--rz-thumbnail-size, var(--rz-size-20));
64
71
  background-color: var(--rz-ressource-card-bg);
@@ -71,7 +78,7 @@
71
78
  max-width: 400px;
72
79
  }
73
80
 
74
- .rz-card-resource__thumbnail {
81
+ .rz-card-resource__thumbnail {
75
82
  width: var(--rz-size);
76
83
  height: var(--rz-size);
77
84
  flex-shrink: 0;
@@ -83,19 +90,19 @@
83
90
  border-radius: var(--rz-radius-md);
84
91
  }
85
92
 
86
- .rz-card-resource__image {
93
+ .rz-card-resource__image {
87
94
  height: 100%;
88
95
  width: 100%;
89
96
  -o-object-fit: cover;
90
97
  object-fit: cover;
91
98
  }
92
99
 
93
- .rz-card-resource__info {
100
+ .rz-card-resource__info {
94
101
  margin-top: var(--rz-size-3);
95
102
  padding-right: 2rem;
96
103
  }
97
104
 
98
- .rz-card-resource__title {
105
+ .rz-card-resource__title {
99
106
  font-variation-settings: 'wght' 600;
100
107
  font-weight: 600;
101
108
  display: flex;
@@ -109,11 +116,11 @@
109
116
  }
110
117
  }
111
118
 
112
- .rz-card-resource__info-text {
119
+ .rz-card-resource__info-text {
113
120
  font-size: var(--rz-text-sm);
114
121
  }
115
122
 
116
- .rz-card-resource__remove {
123
+ .rz-card-resource__remove {
117
124
  position: absolute;
118
125
  color: hsl(var(--rz-color-fg));
119
126
  right: var(--rz-size-2);
@@ -83,9 +83,9 @@
83
83
  --rz-nav-button-height: var(--rz-size-12);
84
84
  --rz-nav-bg: light-dark(hsl(var(--rz-gray-16)), hsl(var(--rz-gray-0)));
85
85
 
86
- --rz-nav-button-bg: light-dark(hsl(var(--rz-gray-19)), hsl(var(--rz-gray-3)));
87
- --rz-nav-group-bg: light-dark(hsl(var(--rz-gray-17)), hsl(var(--rz-gray-2)));
88
- --rz-nav-group-border-color: light-dark(hsl(var(--rz-gray-16)), hsl(var(--rz-gray-3)));
86
+ --rz-nav-button-bg: light-dark(hsl(var(--rz-gray-19)), hsl(var(--rz-gray-2)));
87
+ --rz-nav-group-bg: light-dark(hsl(var(--rz-gray-17)), hsl(var(--rz-gray-1)));
88
+ --rz-nav-group-border-color: light-dark(hsl(var(--rz-gray-16)), hsl(var(--rz-gray-2)));
89
89
  }
90
90
 
91
91
  .rz-nav {
@@ -1,4 +1,4 @@
1
- .rz-toaster__toast {
1
+ .rz-toaster__toast[data-sonner-toast][data-sonner-toast][data-styled='true'] {
2
2
  background-color: hsl(var(--rz-color-bg));
3
3
  border: var(--rz-border);
4
4
  color: var(--rz-gray-2);
@@ -506,15 +506,14 @@ function createDocumentFormState({ initial, element, config, readOnly, key, onNe
506
506
  }
507
507
  return applyAction({ type: 'redirect', location: redirect, status: 301 });
508
508
  }
509
- toast.success(message);
510
509
  // Assign document
511
510
  doc = (data?.document || doc);
511
+ toast.success(message);
512
512
  if (nestedLevel === 0) {
513
513
  await invalidateAll();
514
514
  initialDoc = doc;
515
515
  }
516
516
  else {
517
- toast.success(t__('common.doc_created'));
518
517
  apiProxy.invalidateAll();
519
518
  // Do not redirect on creation if it's a nested form
520
519
  // the form will auto close and we are back to the parent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rimecms",
3
- "version": "0.26.2",
3
+ "version": "0.26.4",
4
4
  "homepage": "https://github.com/bienbiendev/rime",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -26,7 +26,7 @@
26
26
  "license": "MIT",
27
27
  "type": "module",
28
28
  "bin": {
29
- "rime": "./dist/core/dev/cli/index.js"
29
+ "rime": "dist/core/dev/cli/index.js"
30
30
  },
31
31
  "svelte": "./dist/index.js",
32
32
  "types": "./dist/index.d.ts",
@@ -141,9 +141,9 @@
141
141
  "@eslint/compat": "^1.2.5",
142
142
  "@eslint/js": "^9.18.0",
143
143
  "@sveltejs/adapter-node": "^5.2.12",
144
- "@sveltejs/kit": "^2.48.5",
144
+ "@sveltejs/kit": "^2.57.1",
145
145
  "@sveltejs/package": "^2.3.10",
146
- "@sveltejs/vite-plugin-svelte": "^6.0.0",
146
+ "@sveltejs/vite-plugin-svelte": "^7.0.0",
147
147
  "@types/clone-deep": "^4.0.4",
148
148
  "@types/eslint": "^9.6.1",
149
149
  "@types/js-cookie": "^3.0.6",
@@ -165,11 +165,11 @@
165
165
  "prettier": "^3.5.3",
166
166
  "prettier-plugin-svelte": "^3.3.3",
167
167
  "publint": "^0.2.12",
168
- "svelte": "^5.39.9",
169
- "svelte-check": "^4.1.5",
168
+ "svelte": "^5.55.2",
169
+ "svelte-check": "^4.4.6",
170
170
  "typescript": "^5.8.3",
171
171
  "typescript-eslint": "^8.20.0",
172
- "vite": "^7.0.4",
172
+ "vite": "^8.0.8",
173
173
  "vitest": "^4.0.5"
174
174
  },
175
175
  "dependencies": {