-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Améliorer la saisie avec un éditeur WYSIWYG #796
base: main
Are you sure you want to change the base?
The head ref may contain hidden characters: "687-am\u00E9liorer-la-saisie-erreurs-et-recommandations"
Conversation
d5003ef
to
2ba70c2
Compare
2ba70c2
to
31ce9e5
Compare
6672e96
to
b9a24e0
Compare
b9a24e0
to
1250bda
Compare
3251d48
to
9f3a245
Compare
75c5aeb
to
7981839
Compare
* Should handle existing markdown content * The editor is configured with extensions: * all what's in StarterKit * code block lowlight * highlight * link * task * typography (with french double quotes) * Some styles have been added to fit DSFR styling Still work in progress, but a nice start! To do: * image uploading and placement inside editor * menu buttons * accessibility tests and improvements
(and possibly importing JSON content?)
Pruning uploads should not be possible from client web app. This is now only available on backend side. Code has been commented out in case we need to test it quickly for the web app.
63560a0
to
465801e
Compare
If not editable: * avoid adding useless functionnalities * do not display buttons
465801e
to
fb6476b
Compare
* require access token to prune images * add workflow to trigger pruning
@@ -65,6 +65,252 @@ from DSFR links with `target="_blank"` */ | |||
color: var(--background-action-high-error) !important; | |||
} | |||
|
|||
/* Tiptap */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je suggère de déplacer tout le style lié à TipTap dans un fichier dédié, ou le mettre dans Tiptap.vue
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oui, je dirais plutôt un tiptap.css ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Peut-être à garder pour une autre PR histoire de pas avoir trop de choses qui sortent du scope.
display: FileDisplay; | ||
} | ||
|
||
export enum FileDisplay { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
À mettre dans le fichier enums.ts
plutôt du coup ?
<button | ||
:disabled="disabled" | ||
class="fr-btn--sm fr-btn--tertiary" | ||
:class="[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pour éviter à avoir de faire un ternaire, tu peux utiliser cette syntaxe pour appliquer une classe quand une condition est true :
<button
:class="{
'fr-btn--icon-left': labelVisible,
`fr-icon-${icon}`: icon,
'fr-btn--is-toggle': isToggle,
}"
...
>
</button>
v-if="error.notCompliantComment" | ||
:content="error.notCompliantComment" | ||
:editable="false" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On peut simplifier en n'indiquant pas du tout la prop (revient à ce qu'elle soit false
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nettoyer les commentaires.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commentaires à supprimer ?
vertical-align: middle; | ||
} | ||
|
||
/* Testing some different UI for Tiptap editor: */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Supprimer les commentaires
constructor() { | ||
const debugQuery = process.env.DEBUG === "prisma:query"; | ||
let logObject = {}; | ||
if (debugQuery) { | ||
// Note: ideally we would use `emit: "event"` instead of `emit: "stdout"` | ||
// to avoid double logging, but Prisma's query logging is connection-scoped | ||
// rather than query-scoped, so queries using an existing connection | ||
// would not appear in logs | ||
// TODO: improve when upgrading Prisma | ||
logObject = { | ||
log: [ | ||
{ | ||
emit: "stdout", | ||
level: "query" | ||
} | ||
] | ||
}; | ||
} | ||
super(logObject); | ||
} | ||
|
||
async onModuleInit() { | ||
await this.$connect(); | ||
this.$on("query", (query: Prisma.QueryEvent) => { | ||
let q = query.query; | ||
JSON.parse(query.params).forEach((e, i) => { | ||
q = q.replace(`$${i + 1}`, `'${e}'`); | ||
}); | ||
console.log("======================================="); | ||
console.log("--- Prisma Query (with $n replaced) ---"); | ||
console.log(q); | ||
console.log("Duration: " + query.duration + "ms\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a besoin de tout ça ? Ou c'était juste pour débuguer ?
|
||
type PrunableFile = { | ||
fileType: FileType; | ||
id: number; | ||
key: string; | ||
thumbnailKey: string; | ||
}; | ||
|
||
@Injectable() | ||
export class SystemService { | ||
constructor( | ||
private readonly prisma: PrismaService, | ||
private readonly fileStorageService: FileStorageService | ||
) {} | ||
|
||
/** | ||
* Deletes expired AuditFile and StoredFile entries from the database + the associated files from the S3 bucket. | ||
* For each Audit, checks if the file URLs are still present in: | ||
* - notes (AuditFile entries) | ||
* - all criterionResult comments (StoredFile entries) | ||
* If the URL is found, the AuditFile (or StoredFile) is considered expired only if it has been created more than 1 month ago. | ||
* In that case, the entry is deleted from the database and the associated files (1 or 2 if a thumbnail exists) are deleted from the S3 bucket. | ||
* | ||
* Also, checks for obsolete files on the S3 bucket that are not associated anymore to any entry in the database, | ||
* and deletes them if needed (checks all notes and all criteria in the database). | ||
* | ||
* Good to know: A key looks like "audits/lOuFFlopCxZ_mLKzAqpzu/BN2Jhq-iOiTIG96-f3lQU/image.png" | ||
* It contains the audit id, a specific key for the file and the file name | ||
* (or "external" if the image comes from an external URL – i.e. dragged and dropped | ||
* from another website). | ||
*/ | ||
async pruneUploads() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honnêtement, cette fonction fait un peu peur. Je pense qu'on peut envisager de merger ce mécanisme de pruning à part
// async function pruneUploads() { | ||
// await ky.post(`/api/system/prune-uploads`); | ||
// } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// async function pruneUploads() { | |
// await ky.post(`/api/system/prune-uploads`); | |
// } |
window.addEventListener("online", onOnline); | ||
window.addEventListener("offline", onOffline); | ||
|
||
return { | ||
isOnline | ||
// pruneUploads |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// pruneUploads |
Still work in progress, but a nice start!
To do: