How to refactor complex filters and fields for multiple roles? #6764
-
| 
         Hi. I have been using this framework for a large project with Directus Data Provider Nextjs headless mode. Everything has been going well since last year but there are some issues I am facing with maintaining it for large list of fields and filters. Take this for example: const {
    data,
    isLoading,
    error,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteList<DesignResponse>({
    resource: "Designs",
    filters: [
      {
        field: "Quotation",
        operator: "null",
        value: true,
      },
      {
        field: "Visibility_Multiple",
        operator: "containss",
        value: "ReadyToOrder",
      },
      ...(role === "Brands Group"
        ? [
            {
              field: "Brand_Enabled_For_View",
              operator: "eq",
              value: true,
            },
          ]
        : []),
      ...((debouncedMaterialFilter.length > 0
        ? [
            {
              field: "Material.Materials_id.Name",
              operator: "in",
              value: debouncedMaterialFilter.map((item) => item.value),
            },
          ]
        : []) as CrudFilter[]),
      ...((debouncedGender.length > 0
        ? [
            {
              field: "Gender_Type",
              operator: "in",
              value: debouncedGender.map((item) => item.value),
            },
          ]
        : []) as CrudFilter[]),
      ...((debouncedCategoryFilter.length > 0
        ? [
            {
              operator: "or",
              value: [
                {
                  field: "Categories.Design_Categories_id.Name",
                  operator: "in",
                  value: debouncedCategoryFilter.map((item) => item.value),
                },
                {
                  field:
                    "Main_Categories.Design_Main_Categories_id.Design_Categories.Design_Categories_id.Name",
                  operator: "in",
                  value: debouncedCategoryFilter.map((item) => item.value),
                },
              ],
            },
          ]
        : []) as CrudFilter[]),
      ...((debouncedMainCategoryFilter.length > 0
        ? [
            {
              field: "Main_Categories.Design_Main_Categories_id.Name",
              operator: "in",
              value: debouncedMainCategoryFilter.map((item) => item.value),
            },
          ]
        : []) as CrudFilter[]),
      ...((debouncedRTOCost.length > 0
        ? [
            {
              field: "RTO_Cost",
              operator: "in",
              value: debouncedRTOCost.map((item) => item.value),
            },
          ]
        : []) as CrudFilter[]),
      ...((debouncedRTOMOQ.length > 0
        ? [
            {
              field: "RTO_MOQ",
              operator: "in",
              value: debouncedRTOMOQ.map((item) => item.value),
            },
          ]
        : []) as CrudFilter[]),
      ...((debouncedBrandFilter.length > 0
        ? [
            {
              field: "RTO_Brand",
              operator: "in",
              value: debouncedBrandFilter.map((item) => item.value),
            },
          ]
        : []) as CrudFilter[]),
      ...((debouncedEstimateOrderTimeFilter.length > 0
        ? [
            {
              field: "Estimate_Order_Time",
              operator: "in",
              value: debouncedEstimateOrderTimeFilter.map((item) => item.value),
            },
          ]
        : []) as CrudFilter[]),
      ...((role === "Administrator" || role === "Manager"
        ? [
            ...((debouncedSupplier.length > 0
              ? [
                  {
                    field: "Supplier.Suppliers_id.Name",
                    operator: "in",
                    value: debouncedSupplier.map((item) => item.value),
                  },
                ]
              : []) as CrudFilter[]),
          ]
        : []) as CrudFilter[]),
    ] as CrudFilter[],
    sorters: [
      {
        field: "date_created",
        order: debouncedSortOrder === "none" ? undefined! : debouncedSortOrder,
      },
      {
        field: "RTO_Cost",
        order:
          debouncedRTOCostSort === "none" ? undefined! : debouncedRTOCostSort,
      },
      {
        field: "RTO_MOQ",
        order:
          debouncedRTOMOQSort === "none" ? undefined! : debouncedRTOMOQSort,
      },
    ],
    meta: {
      fields: [
        "id",
        "Name",
        "Main_Photo.filename_disk",
        "Notes",
        "MOQ",
        "Cost",
        "Description",
        "Supplier.Suppliers_id.Country",
        "RTO_Cost",
        "RTO_MOQ",
        "Main_Categories.Design_Main_Categories_id.Name",
        "Main_Categories.Design_Main_Categories_id.id",
        "Categories.Design_Categories_id.Name",
        "Categories.Design_Categories_id.id",
        "Gender_Type",
        "Details",
        "Visibility",
        "Select_Sizes",
        "Available_Sizes",
        // "Colours_Available.*",
        {
          Material: [
            {
              Designs_id: ["id"],
              Materials_id: ["id", "Name", "made_in"],
            },
          ],
          Colours_Available_To_Select: [
            {
              Colors_id: ["id", "Color_Name", "Color_Code", "Color_Image"],
            },
          ],
          Design_Details: [
            {
              Design_Details_id: [
                "id",
                "Name",
                "Description",
                {
                  Image: ["filename_disk"],
                },
              ],
            },
          ],
        },
        "Additional_Photos.directus_files_id",
      ]
        .concat(
          role !== "Brands Group" ? ["Internal_CMT_Cost", "Supplier_Code"] : []
        )
        .concat(
          role === "Brands Group"
            ? ["Brand_Enabled_For_View", "Estimate_Order_Time"]
            : []
        )
        .concat(role === "Supplier Group" ? ["Material.Materials_id.Code"] : [])
        .concat(
          (["Administrator", "Supplier Group"] as Role[]).includes(role)
            ? ["Internal_CMT_Currency"]
            : []
        ),
    },
    pagination: {
      pageSize: 20,
    },
  });As you can see this is very complicated to read and maintain while validating this with the requirements. I thought of using GraphQL then adding the queries here based on role but this will require a full rewrite of the project. I am looking for some advice on how to approach this scenario. Refine.dev's architecture is fine when there are a small number of filters and fields but when it gets larger, I would like to have some typings for fields and filters as I have to fully rely on the API documentation currently with no intellisense on these.  | 
  
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
| 
         Hello @SadmanYasar. I think you can extract these parameters into a different hook, that would make it easier to read and handle your logic.  | 
  
Beta Was this translation helpful? Give feedback.
Hello @SadmanYasar. I think you can extract these parameters into a different hook, that would make it easier to read and handle your logic.