Skip to content

Instantly share code, notes, and snippets.

View tchak's full-sized avatar
GH drop ICE

Paul Chavard tchak

GH drop ICE
View GitHub Profile
@tchak
tchak / README.md
Last active June 30, 2023 17:36
DS + Datomic

C'est une implémentation minimale du modèle vers lequel je propose de se diriger. L'implémentation est en TypeScript car les types aident beaucoup à la compréhension de ce genre de code. Et je ne connais pas bien Sorbet :)

  • Field -> TypeDeChamp
  • Datom -> Champ
  • Attribute -> le Champ projeté à travers un TypeDeChamp
  • Section -> Avec FieldCardinality.ONE c'est une section ou un bloc simple, avec FieldCardinality.MANY c'est un bloc répétable

Points intéressants :

  • Les TypeDeChamp sont une liste à un seul niveau. Il n'y a pas d'arborescence même pour les bloc répétable.
@tchak
tchak / exemple.gql
Created May 4, 2023 15:11
exemple graphql
query getDemarche($demarcheNumber: Int!) {
demarche(number: $demarcheNumber) {
id
dossiers {
nodes {
id
demandeur {
... on PersonnePhysique {
civilite
nom
@tchak
tchak / dossierAccepter.py
Last active January 27, 2022 08:42
GraphQL Request Example
import requests
token = "..."
dossierNumber = 123
motivation = "..."
headers = {
'authorization': 'Bearer %s' % token,
'content-type': 'application/json'
}
import type { Maybe } from 'true-myth/maybe';
import { Result, ok, err, isInstance as isResult } from 'true-myth/result';
export interface Task<Value, Error> {
(): Promise<Result<Value, Error>>;
map<MappedValue>(f: (t: Value) => MappedValue): Task<MappedValue, Error>;
mapErr<MappedError>(f: (e: Error) => MappedError): Task<Value, MappedError>;
flatMap<MappedValue, MappedError>(
f: (t: Value) => Task<MappedValue, MappedError>
): Task<MappedValue, Error | MappedError>;
@tchak
tchak / with-body.ts
Last active May 12, 2021 18:40
Remix withBody
import type { ActionFunction, Request } from 'remix';
import { BaseSchema, ValidationError } from 'yup';
type NextActionFunction<Body> = (body: Body) => ReturnType<ActionFunction>;
export async function withBody(
request: Request,
config: (router: ActionRouter) => void
) {
const router = new ActionRouter();
@tchak
tchak / remix-refetch.tsx
Last active November 5, 2022 05:10
Remix Refetch
import { useCallback, useEffect, useState, useRef } from 'react';
import { useLocation } from 'react-router-dom';
import type { ActionFunction } from 'remix';
import { redirect, useSubmit } from 'remix';
export const action: ActionFunction = async ({ request }) => {
const body = new URLSearchParams(await request.text());
return redirect(String(body.get('path')));
};
@tchak
tchak / ClientOnly.tsx
Created May 5, 2021 20:32
ClientOnly
// global hydrating so future components don't do this dance, they just render
let hydrating = true;
// Component that renders `null` on the server and the initial browser render
// (while it's "hydrating")
function ClientOnly({ children }) {
// set initial state to whatever the global hydrating is, so once the app is
// hydrated, these components just render, no dance
let [hydrated, setHydrated] = useState(() => !hydrating);
query exportDemarche($demarcheNumber: Int!, $after: String) {
demarche(number: $demarcheNumber) {
number
dossiers(first: 100, after: $after) {
pageInfo {
hasNextPage
endCursor
}
nodes {
...DossierFragment
class Survey < ApplicationRecord
has_many :revisions
belongs_to :draft_revision
belongs_to :published_revision
has_many :draft_fields, through: :draft_revision
has_many :fields, through: :published_revision
def publish
self.published_revision = draft_revision

Pagination GraphQL

La pagination sur l'API GraphQL se fait par "curseur". Ça veut dire que pour récupérer la prochaine page il faut passer à l'API le "curseur" de la fin de la page précédente.

Voici un exemple. On commence par faire une query pour récupérer les 100 premiers dossiers.

query {
  demarche(number: 123) {
    dossiers(first: 100) {
      pageInfo {