Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/form/question/models.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -402,4 +402,40 @@ namespace CoreSystem.Forms {
@doc("If set, choices are dynamically generated from answers to this question.")
sourceId?: uuid;
}

@doc("A single answer option available for filtering.")
model FilterAnswerItem {
@doc("The text displayed to the user in the filter UI.")
displayValue: string;

@doc("The raw value used for backend querying and matching.")
matchValue: string;

@doc("Whether this filter option is selected. Defaults to false from server.")
selected: boolean;
}

@doc("Response model for getting question filters.")
@example(#{
viewId: "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
formId: "550e8400-e29b-41d4-a716-446655440000",
questionId: "74723192-bc11-412e-a576-928b76c8c9e0",
answers: #[
#{ displayValue: "開發部", matchValue: "abc-123-def", selected: false },
#{ displayValue: "品牌部", matchValue: "ghi-456-jkl", selected: false }
]
})
model QuestionFiltersResponse {
@doc("The unique identifier of the view.")
viewId: uuid;

@doc("The unique identifier of the form.")
formId: uuid;

@doc("The unique identifier of the question.")
questionId: uuid;

@doc("The list of available unique answers for this question.")
answers: FilterAnswerItem[];
}
Comment thread
dytsou marked this conversation as resolved.
}
21 changes: 20 additions & 1 deletion src/form/question/operations.tsp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import "../response/models.tsp";

using Http;

@tag("Forms")
Expand Down Expand Up @@ -37,4 +39,21 @@ namespace CoreSystem.Forms {
op deleteQuestion(@path sectionId: uuid, @path questionId: uuid): {
@statusCode statusCode: 204;
};
}

@summary("Get Filters")
@doc("Filter and query distinct answers of the question for filtering.")
@route("/forms/{formId}/views/{viewId}/questions/{questionId}/filters")
@post
op filterAndQueryAnswers(
@path formId: uuid,
@path viewId: uuid,
@path questionId: uuid,
@body req: CoreSystem.Responses.AnswerFilterRequest
): {
@statusCode statusCode: 200;
@body response: QuestionFiltersResponse;
} | {
@statusCode statusCode: 404;
Comment thread
dytsou marked this conversation as resolved.
@body error: NotFound;
};
}
40 changes: 40 additions & 0 deletions src/form/response/models.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,44 @@ namespace CoreSystem.Responses {
questionIds: uuid[];
}

@doc("A single answer option selected by the user")
model QueryFilterAnswerItem {
@doc("The raw value used for backend querying and matching.")
option: uuid;
}

@doc("Filter group for a specific question")
model ResponseQueryFilter {
@doc("The unique identifier of the question.")
questionId: uuid;

@doc("The list of answers selected for this question.")
answers: QueryFilterAnswerItem[];
}

@doc("Request model for filtering form responses")
@example(#{
filters: #[
#{
questionId: "a1b2c3d4-1111-2222-3333-444455556666",
answers: #[
#{ option: "9a843aa0-8451-4e3b-b6a0-8c0e994e9040" },
#{ option: "00000000-0000-0000-0000-000000000001" }
]
}
]
})
model AnswerFilterRequest {
@doc("The List of questions selected.")
filters: ResponseQueryFilter[];
}

@doc("Response model for filtering form responses")
model AnswerFilterResponse {
@doc("The form unique identifier.")
formId: uuid;

@doc("The form responses that match the selected answers.")
responses: ExportRow[];
}
}
15 changes: 15 additions & 0 deletions src/form/response/operations.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,19 @@ namespace CoreSystem.Responses {
@statusCode statusCode: 404;
@body error: NotFound;
};

@summary("Filter And Query Form Responses")
@doc("Filter and query form responses based on a list of selected question answers.")
@route("/forms/{formId}/responses/query")
@post
op filterAndQueryFormResponses(@path formId: uuid, @body req: AnswerFilterRequest): {
@statusCode statusCode: 200;
@body response: AnswerFilterResponse;
} | {
@statusCode statusCode: 400;
Comment thread
dytsou marked this conversation as resolved.
@body error: BadRequest;
} | {
@statusCode statusCode: 404;
@body error: NotFound;
};
}
18 changes: 18 additions & 0 deletions src/form/view/models.tsp
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
using Http;

namespace CoreSystem.Views {

@doc("A single question option available for filtering.")
model Column{
@doc("The question's unique identifier.")
questionId: uuid;

@doc("The text displayed to the user in the filter UI.")
questionTitle: string;
}

@doc("Response model for a single form view.")
@example(#{
id: "f1a2b3c4-5d6e-7f8a-9b0c-1d2e3f4a5b6c",
Expand All @@ -9,7 +19,12 @@ namespace CoreSystem.Views {
order: 0,
createdAt: utcDateTime.fromISO("2025-01-15T10:00:00Z"),
updatedAt: utcDateTime.fromISO("2025-02-10T14:30:00Z"),
columns: #[
#{ questionId: "f81d4fae-7dec-11d0-a765-00a0c91e6bf6", questionTitle: "部門" },
#{ questionId: "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b", questionTitle: "姓名" }
]
})

model ViewResponse {
@doc("The view's unique identifier.")
id: uuid;
Expand All @@ -28,6 +43,9 @@ namespace CoreSystem.Views {

@doc("The last updated timestamp of the view.")
updatedAt: utcDateTime;

@doc("The columns of the filters.")
columns: Column[];
}

@doc("Request model for updating a view. Only provided fields will be updated.")
Expand Down
Loading