Skip to content

Commit

Permalink
fix: Resource created at filter
Browse files Browse the repository at this point in the history
  • Loading branch information
adityachoudhari26 committed Nov 28, 2024
1 parent b136e7d commit c960cbb
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ import {
SelectTrigger,
SelectValue,
} from "@ctrlplane/ui/select";
import { ColumnOperator } from "@ctrlplane/validators/conditions";
import {
ColumnOperator,
DateOperator,
FilterType,
} from "@ctrlplane/validators/conditions";
import {
doesConvertingToComparisonRespectMaxDepth,
isComparisonCondition,
Expand Down Expand Up @@ -317,6 +321,18 @@ export const ComparisonConditionRender: React.FC<
>
Provider
</DropdownMenuItem>
<DropdownMenuItem
onClick={() =>
addCondition({
type: FilterType.CreatedAt,
operator: DateOperator.Before,
value: new Date().toISOString(),
})
}
>
Created at
</DropdownMenuItem>

{depth < 2 && (
<DropdownMenuItem
onClick={() =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type {
CreatedAtCondition,
DateOperatorType,
} from "@ctrlplane/validators/conditions";
import type { DateValue } from "@internationalized/date";

import type { TargetConditionRenderProps } from "./target-condition-props";
import { DateConditionRender } from "../filter/DateConditionRender";

export const ResourceCreatedAtConditionRender: React.FC<
TargetConditionRenderProps<CreatedAtCondition>
> = ({ condition, onChange, className }) => {
const setDate = (t: DateValue) =>
onChange({
...condition,
value: t
.toDate(Intl.DateTimeFormat().resolvedOptions().timeZone)
.toISOString(),
});

const setOperator = (operator: DateOperatorType) =>
onChange({ ...condition, operator });

return (
<DateConditionRender
setDate={setDate}
setOperator={setOperator}
value={condition.value}
operator={condition.operator}
type="Created at"
className={className}
/>
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { MetadataCondition } from "@ctrlplane/validators/conditions";
import type {
CreatedAtCondition,
MetadataCondition,
} from "@ctrlplane/validators/conditions";
import type {
ComparisonCondition,
IdentifierCondition,
Expand All @@ -8,6 +11,7 @@ import type {
ResourceCondition,
} from "@ctrlplane/validators/resources";
import React from "react";
import { format } from "date-fns";
import _ from "lodash";

import { cn } from "@ctrlplane/ui";
Expand All @@ -17,9 +21,10 @@ import {
HoverCardContent,
HoverCardTrigger,
} from "@ctrlplane/ui/hover-card";
import { ColumnOperator } from "@ctrlplane/validators/conditions";
import { ColumnOperator, DateOperator } from "@ctrlplane/validators/conditions";
import {
isComparisonCondition,
isCreatedAtCondition,
isIdentifierCondition,
isKindCondition,
isMetadataCondition,
Expand All @@ -44,6 +49,10 @@ const operatorVerbs = {
[ColumnOperator.StartsWith]: "starts with",
[ColumnOperator.EndsWith]: "ends with",
[ColumnOperator.Contains]: "contains",
[DateOperator.Before]: "before",
[DateOperator.After]: "after",
[DateOperator.BeforeOrOn]: "before or on",
[DateOperator.AfterOrOn]: "after or on",
};

const ConditionBadge: React.FC<{
Expand Down Expand Up @@ -208,6 +217,20 @@ const StringifiedProviderCondition: React.FC<{
);
};

const StringifiedCreatedAtCondition: React.FC<{
condition: CreatedAtCondition;
}> = ({ condition }) => (
<ConditionBadge>
<span className="text-white">created</span>
<span className="text-muted-foreground">
{operatorVerbs[condition.operator]}
</span>
<span className="text-white">
{format(condition.value, "MMM d, yyyy, h:mma")}
</span>
</ConditionBadge>
);

const StringifiedTargetCondition: React.FC<{
condition: ResourceCondition;
depth?: number;
Expand Down Expand Up @@ -242,6 +265,9 @@ const StringifiedTargetCondition: React.FC<{

if (isProviderCondition(condition))
return <StringifiedProviderCondition condition={condition} />;

if (isCreatedAtCondition(condition))
return <StringifiedCreatedAtCondition condition={condition} />;
};

export const TargetConditionBadge: React.FC<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from "react";

import {
isComparisonCondition,
isCreatedAtCondition,
isIdentifierCondition,
isKindCondition,
isMetadataCondition,
Expand All @@ -16,6 +17,7 @@ import { IdentifierConditionRender } from "./IdentifierConditionRender";
import { KindConditionRender } from "./KindConditionRender";
import { NameConditionRender } from "./NameConditionRender";
import { ProviderConditionRender } from "./ProviderConditionRender";
import { ResourceCreatedAtConditionRender } from "./ResourceCreatedAtConditionRender";
import { TargetMetadataConditionRender } from "./TargetMetadataConditionRender";

/**
Expand Down Expand Up @@ -80,5 +82,14 @@ export const TargetConditionRender: React.FC<
/>
);

if (isCreatedAtCondition(condition))
return (
<ResourceCreatedAtConditionRender
condition={condition}
onChange={onChange}
className={className}
/>
);

return null;
};
23 changes: 22 additions & 1 deletion packages/db/src/schema/resource.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { MetadataCondition } from "@ctrlplane/validators/conditions";
import type {
CreatedAtCondition,
MetadataCondition,
} from "@ctrlplane/validators/conditions";
import type {
IdentifierCondition,
NameCondition,
Expand All @@ -7,8 +10,12 @@ import type {
import type { InferInsertModel, InferSelectModel, SQL } from "drizzle-orm";
import {
exists,
gt,
gte,
ilike,
like,
lt,
lte,
not,
notExists,
or,
Expand All @@ -33,6 +40,8 @@ import { z } from "zod";
import {
ColumnOperator,
ComparisonOperator,
DateOperator,
FilterType,
MetadataOperator,
} from "@ctrlplane/validators/conditions";
import {
Expand Down Expand Up @@ -243,6 +252,16 @@ const buildNameCondition = (tx: Tx, cond: NameCondition): SQL => {
return sql`${resource.name} ~ ${cond.value}`;
};

const buildCreatedAtCondition = (tx: Tx, cond: CreatedAtCondition): SQL => {
const date = new Date(cond.value);
if (cond.operator === DateOperator.Before)
return lt(resource.createdAt, date);
if (cond.operator === DateOperator.After) return gt(resource.createdAt, date);
if (cond.operator === DateOperator.BeforeOrOn)
return lte(resource.createdAt, date);
return gte(resource.createdAt, date);
};

const buildCondition = (tx: Tx, cond: ResourceCondition): SQL => {
if (cond.type === ResourceFilterType.Metadata)
return buildMetadataCondition(tx, cond);
Expand All @@ -254,6 +273,8 @@ const buildCondition = (tx: Tx, cond: ResourceCondition): SQL => {
return eq(resource.providerId, cond.value);
if (cond.type === ResourceFilterType.Identifier)
return buildIdentifierCondition(tx, cond);
if (cond.type === FilterType.CreatedAt)
return buildCreatedAtCondition(tx, cond);

if (cond.conditions.length === 0) return sql`FALSE`;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { z } from "zod";

import type { MetadataCondition } from "../../conditions/index.js";
import type {
CreatedAtCondition,
MetadataCondition,
} from "../../conditions/index.js";
import type { IdentifierCondition } from "./identifier-condition.js";
import type { KindCondition } from "./kind-condition.js";
import type { NameCondition } from "./name-condition.js";
import type { ProviderCondition } from "./provider-condition.js";
import { metadataCondition } from "../../conditions/index.js";
import {
createdAtCondition,
metadataCondition,
} from "../../conditions/index.js";
import { identifierCondition } from "./identifier-condition.js";
import { kindCondition } from "./kind-condition.js";
import { nameCondition } from "./name-condition.js";
Expand All @@ -24,6 +30,7 @@ export const comparisonCondition: z.ZodType<ComparisonCondition> = z.lazy(() =>
nameCondition,
providerCondition,
identifierCondition,
createdAtCondition,
]),
),
}),
Expand All @@ -40,5 +47,6 @@ export type ComparisonCondition = {
| NameCondition
| ProviderCondition
| IdentifierCondition
| CreatedAtCondition
>;
};
19 changes: 16 additions & 3 deletions packages/validators/src/resources/conditions/resource-condition.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { z } from "zod";

import type { MetadataCondition } from "../../conditions/index.js";
import type {
CreatedAtCondition,
MetadataCondition,
} from "../../conditions/index.js";
import type { ComparisonCondition } from "./comparison-condition.js";
import type { IdentifierCondition } from "./identifier-condition.js";
import type { KindCondition } from "./kind-condition.js";
import type { NameCondition } from "./name-condition.js";
import type { ProviderCondition } from "./provider-condition.js";
import { metadataCondition } from "../../conditions/index.js";
import {
createdAtCondition,
FilterType,
metadataCondition,
} from "../../conditions/index.js";
import { comparisonCondition } from "./comparison-condition.js";
import { identifierCondition } from "./identifier-condition.js";
import { kindCondition } from "./kind-condition.js";
Expand All @@ -19,7 +26,8 @@ export type ResourceCondition =
| KindCondition
| NameCondition
| ProviderCondition
| IdentifierCondition;
| IdentifierCondition
| CreatedAtCondition;

export const resourceCondition = z.union([
comparisonCondition,
Expand All @@ -28,6 +36,7 @@ export const resourceCondition = z.union([
nameCondition,
providerCondition,
identifierCondition,
createdAtCondition,
]);

export enum ResourceOperator {
Expand Down Expand Up @@ -104,6 +113,10 @@ export const isIdentifierCondition = (
): condition is IdentifierCondition =>
condition.type === ResourceFilterType.Identifier;

export const isCreatedAtCondition = (
condition: ResourceCondition,
): condition is CreatedAtCondition => condition.type === FilterType.CreatedAt;

export const isValidTargetCondition = (
condition: ResourceCondition,
): boolean => {
Expand Down

0 comments on commit c960cbb

Please sign in to comment.