From 016e102dbcb7da9608152dcbd6c2686565bd0c70 Mon Sep 17 00:00:00 2001 From: Brooks Patton Date: Thu, 15 Jun 2023 09:02:22 -0600 Subject: [PATCH] show completed articles (#19) * wip - creating next buttons for articles * wip marking user articles as started * marking user article complete when hitting the button * marking articles as completed at load * wip - marking the completed articles completed live and not just in database. Probably need to do an upsert or something else * marking articles as started and completed at the right times * fixed errors and warningsO * using latest ycl * fixed clippy warnings * running cargo check only on this library * fixing bug due to https://github.com/futursolo/stylist-rs/issues/120 * using an older version of rust * fixed cargo formatting problem * fixed cargo formatting problem --- .github/workflows/main.yml | 7 +- Cargo.lock | 2 +- Cargo.toml | 5 +- .../api_complete_user_article.graphql | 5 + .../mutations/api_insert_user_article.graphql | 6 + database/queries/get_all_courses.graphql | 4 + database/schema.json | 3654 ++++++++++++++++- src/api/mod.rs | 39 +- src/auth/mod.rs | 2 +- src/components/course_nav.rs | 7 + src/components/mod.rs | 1 + src/components/next_article.rs | 57 + src/database_queries.rs | 16 + src/pages/course_access_article.rs | 91 +- src/stores/main_store.rs | 14 + src/types.rs | 50 +- 16 files changed, 3741 insertions(+), 219 deletions(-) create mode 100644 database/mutations/api_complete_user_article.graphql create mode 100644 database/mutations/api_insert_user_article.graphql create mode 100644 src/components/next_article.rs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0265d4b..b3ece6b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,8 +6,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 + - name: Install latest nightly + uses: actions-rs/toolchain@v1 + with: + toolchain: 1.69.0 + components: rustfmt, clippy - name: cargo check - run: touch .env && cargo check + run: touch .env && cargo check --lib env: RUST_ENV: test GRAPHQL_URI: http://localhost:8081 diff --git a/Cargo.lock b/Cargo.lock index fa02213..abbfee3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1576,7 +1576,7 @@ checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "ycl" version = "0.1.0" -source = "git+https://github.com/brooks-builds/ycl?rev=c01c7f6#c01c7f695bfca0c1b0636c3d193f2c79e09afdbc" +source = "git+https://github.com/brooks-builds/ycl?rev=79d332c#79d332c3766c6abd65e61c0d71f7ac16dffb697b" dependencies = [ "chrono", "gloo", diff --git a/Cargo.toml b/Cargo.toml index 19dfdca..aafb34b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] yew = { version = "0.20.0", features = ["csr"] } -ycl = { git = "https://github.com/brooks-builds/ycl", rev = "c01c7f6" } +ycl = { git = "https://github.com/brooks-builds/ycl", rev = "79d332c" } # ycl = { path = "../ycl/" } yew-router = "0.17.0" gloo = "0.8.0" @@ -26,3 +26,6 @@ stylist = { version = "0.12.0", features = ["yew"] } url = "2.3.1" wasm-bindgen-futures = "0.4.34" eyre = "0.6.8" + +[profile.dev.package.wasm-bindgen] +debug-assertions = false diff --git a/database/mutations/api_complete_user_article.graphql b/database/mutations/api_complete_user_article.graphql new file mode 100644 index 0000000..da2d93b --- /dev/null +++ b/database/mutations/api_complete_user_article.graphql @@ -0,0 +1,5 @@ +mutation ApiCompleteUserArticle($user_id: Int!, $article_id: Int!) { + update_user_articles(where: {user_id: {_eq: $user_id}, article_id: {_eq: $article_id}}, _set: {completed_at: "NOW()"}) { + affected_rows + } +} \ No newline at end of file diff --git a/database/mutations/api_insert_user_article.graphql b/database/mutations/api_insert_user_article.graphql new file mode 100644 index 0000000..6afd52e --- /dev/null +++ b/database/mutations/api_insert_user_article.graphql @@ -0,0 +1,6 @@ +mutation ApiInsertUserArticle($user_id: Int!, $article_id: Int!) { + insert_user_articles_one(object: {article_id: $article_id, user_id: $user_id}) { + article_id + user_id + } +} \ No newline at end of file diff --git a/database/queries/get_all_courses.graphql b/database/queries/get_all_courses.graphql index f48913b..fba3c5c 100644 --- a/database/queries/get_all_courses.graphql +++ b/database/queries/get_all_courses.graphql @@ -40,5 +40,9 @@ query ApiGetAllData { id } } + articles { + article_id + completed_at + } } } \ No newline at end of file diff --git a/database/schema.json b/database/schema.json index 89e20ea..84e5d2c 100644 --- a/database/schema.json +++ b/database/schema.json @@ -6295,6 +6295,180 @@ "ofType": null } } + }, + { + "args": [ + { + "defaultValue": null, + "description": "distinct select on columns", + "name": "distinct_on", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_articles_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "limit the number of rows returned", + "name": "limit", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "skip the first n rows. Use only with order_by", + "name": "offset", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sort the rows by one or more columns", + "name": "order_by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_order_by", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "filter the rows returned", + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": "An array relationship", + "isDeprecated": false, + "name": "user_articles", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "user_articles", + "ofType": null + } + } + } + } + }, + { + "args": [ + { + "defaultValue": null, + "description": "distinct select on columns", + "name": "distinct_on", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_articles_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "limit the number of rows returned", + "name": "limit", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "skip the first n rows. Use only with order_by", + "name": "offset", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sort the rows by one or more columns", + "name": "order_by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_order_by", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "filter the rows returned", + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": "An aggregate relationship", + "isDeprecated": false, + "name": "user_articles_aggregate", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "user_articles_aggregate", + "ofType": null + } + } } ], "inputFields": null, @@ -6960,6 +7134,26 @@ "name": "String_comparison_exp", "ofType": null } + }, + { + "defaultValue": null, + "description": null, + "name": "user_articles", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_articles_aggregate", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_aggregate_bool_exp", + "ofType": null + } } ], "interfaces": null, @@ -7079,6 +7273,16 @@ "name": "String", "ofType": null } + }, + { + "defaultValue": null, + "description": null, + "name": "user_articles", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_arr_rel_insert_input", + "ofType": null + } } ], "interfaces": null, @@ -7513,6 +7717,16 @@ "name": "order_by", "ofType": null } + }, + { + "defaultValue": null, + "description": null, + "name": "user_articles_aggregate", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_aggregate_order_by", + "ofType": null + } } ], "interfaces": null, @@ -15848,19 +16062,19 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "user_courses_bool_exp", + "name": "user_articles_bool_exp", "ofType": null } } } ], "deprecationReason": null, - "description": "delete data from the table: \"user_courses\"", + "description": "delete data from the table: \"user_articles\"", "isDeprecated": false, - "name": "delete_user_courses", + "name": "delete_user_articles", "type": { "kind": "OBJECT", - "name": "user_courses_mutation_response", + "name": "user_articles_mutation_response", "ofType": null } }, @@ -15869,7 +16083,7 @@ { "defaultValue": null, "description": null, - "name": "course_id", + "name": "article_id", "type": { "kind": "NON_NULL", "name": null, @@ -15896,12 +16110,12 @@ } ], "deprecationReason": null, - "description": "delete single row from the table: \"user_courses\"", + "description": "delete single row from the table: \"user_articles\"", "isDeprecated": false, - "name": "delete_user_courses_by_pk", + "name": "delete_user_articles_by_pk", "type": { "kind": "OBJECT", - "name": "user_courses", + "name": "user_articles", "ofType": null } }, @@ -15916,19 +16130,19 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "users_bool_exp", + "name": "user_courses_bool_exp", "ofType": null } } } ], "deprecationReason": null, - "description": "delete data from the table: \"users\"", + "description": "delete data from the table: \"user_courses\"", "isDeprecated": false, - "name": "delete_users", + "name": "delete_user_courses", "type": { "kind": "OBJECT", - "name": "users_mutation_response", + "name": "user_courses_mutation_response", "ofType": null } }, @@ -15937,7 +16151,21 @@ { "defaultValue": null, "description": null, - "name": "id", + "name": "course_id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", "type": { "kind": "NON_NULL", "name": null, @@ -15950,12 +16178,12 @@ } ], "deprecationReason": null, - "description": "delete single row from the table: \"users\"", + "description": "delete single row from the table: \"user_courses\"", "isDeprecated": false, - "name": "delete_users_by_pk", + "name": "delete_user_courses_by_pk", "type": { "kind": "OBJECT", - "name": "users", + "name": "user_courses", "ofType": null } }, @@ -15963,28 +16191,82 @@ "args": [ { "defaultValue": null, - "description": "the rows to be inserted", - "name": "objects", + "description": "filter the rows which have to be deleted", + "name": "where", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "INPUT_OBJECT", - "name": "article_content_insert_input", - "ofType": null - } - } + "kind": "INPUT_OBJECT", + "name": "users_bool_exp", + "ofType": null } } - }, - { - "defaultValue": null, + } + ], + "deprecationReason": null, + "description": "delete data from the table: \"users\"", + "isDeprecated": false, + "name": "delete_users", + "type": { + "kind": "OBJECT", + "name": "users_mutation_response", + "ofType": null + } + }, + { + "args": [ + { + "defaultValue": null, + "description": null, + "name": "id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + } + ], + "deprecationReason": null, + "description": "delete single row from the table: \"users\"", + "isDeprecated": false, + "name": "delete_users_by_pk", + "type": { + "kind": "OBJECT", + "name": "users", + "ofType": null + } + }, + { + "args": [ + { + "defaultValue": null, + "description": "the rows to be inserted", + "name": "objects", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "article_content_insert_input", + "ofType": null + } + } + } + } + }, + { + "defaultValue": null, "description": "upsert condition", "name": "on_conflict", "type": { @@ -16677,6 +16959,88 @@ "ofType": null } }, + { + "args": [ + { + "defaultValue": null, + "description": "the rows to be inserted", + "name": "objects", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_insert_input", + "ofType": null + } + } + } + } + }, + { + "defaultValue": null, + "description": "upsert condition", + "name": "on_conflict", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_on_conflict", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": "insert data into the table: \"user_articles\"", + "isDeprecated": false, + "name": "insert_user_articles", + "type": { + "kind": "OBJECT", + "name": "user_articles_mutation_response", + "ofType": null + } + }, + { + "args": [ + { + "defaultValue": null, + "description": "the row to be inserted", + "name": "object", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_insert_input", + "ofType": null + } + } + }, + { + "defaultValue": null, + "description": "upsert condition", + "name": "on_conflict", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_on_conflict", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": "insert a single row into the table: \"user_articles\"", + "isDeprecated": false, + "name": "insert_user_articles_one", + "type": { + "kind": "OBJECT", + "name": "user_articles", + "ofType": null + } + }, { "args": [ { @@ -17991,6 +18355,139 @@ } } }, + { + "args": [ + { + "defaultValue": null, + "description": "increments the numeric columns with given value of the filtered values", + "name": "_inc", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_inc_input", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sets the columns of the filtered rows to the given values", + "name": "_set", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_set_input", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "filter the rows which have to be updated", + "name": "where", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + } + ], + "deprecationReason": null, + "description": "update data of the table: \"user_articles\"", + "isDeprecated": false, + "name": "update_user_articles", + "type": { + "kind": "OBJECT", + "name": "user_articles_mutation_response", + "ofType": null + } + }, + { + "args": [ + { + "defaultValue": null, + "description": "increments the numeric columns with given value of the filtered values", + "name": "_inc", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_inc_input", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sets the columns of the filtered rows to the given values", + "name": "_set", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_set_input", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "pk_columns", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_pk_columns_input", + "ofType": null + } + } + } + ], + "deprecationReason": null, + "description": "update single row of the table: \"user_articles\"", + "isDeprecated": false, + "name": "update_user_articles_by_pk", + "type": { + "kind": "OBJECT", + "name": "user_articles", + "ofType": null + } + }, + { + "args": [ + { + "defaultValue": null, + "description": "updates to execute, in order", + "name": "updates", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_updates", + "ofType": null + } + } + } + } + } + ], + "deprecationReason": null, + "description": "update multiples rows of table: \"user_articles\"", + "isDeprecated": false, + "name": "update_user_articles_many", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "user_articles_mutation_response", + "ofType": null + } + } + }, { "args": [ { @@ -20156,7 +20653,7 @@ "name": null, "ofType": { "kind": "ENUM", - "name": "user_courses_select_column", + "name": "user_articles_select_column", "ofType": null } } @@ -20194,7 +20691,222 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "user_courses_order_by", + "name": "user_articles_order_by", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "filter the rows returned", + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": "An array relationship", + "isDeprecated": false, + "name": "user_articles", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "user_articles", + "ofType": null + } + } + } + } + }, + { + "args": [ + { + "defaultValue": null, + "description": "distinct select on columns", + "name": "distinct_on", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_articles_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "limit the number of rows returned", + "name": "limit", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "skip the first n rows. Use only with order_by", + "name": "offset", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sort the rows by one or more columns", + "name": "order_by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_order_by", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "filter the rows returned", + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": "An aggregate relationship", + "isDeprecated": false, + "name": "user_articles_aggregate", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "user_articles_aggregate", + "ofType": null + } + } + }, + { + "args": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + } + ], + "deprecationReason": null, + "description": "fetch data from the table: \"user_articles\" using primary key columns", + "isDeprecated": false, + "name": "user_articles_by_pk", + "type": { + "kind": "OBJECT", + "name": "user_articles", + "ofType": null + } + }, + { + "args": [ + { + "defaultValue": null, + "description": "distinct select on columns", + "name": "distinct_on", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_courses_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "limit the number of rows returned", + "name": "limit", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "skip the first n rows. Use only with order_by", + "name": "offset", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sort the rows by one or more columns", + "name": "order_by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_courses_order_by", "ofType": null } } @@ -24372,7 +25084,7 @@ "name": null, "ofType": { "kind": "ENUM", - "name": "user_courses_select_column", + "name": "user_articles_select_column", "ofType": null } } @@ -24410,7 +25122,7 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "user_courses_order_by", + "name": "user_articles_order_by", "ofType": null } } @@ -24422,7 +25134,7 @@ "name": "where", "type": { "kind": "INPUT_OBJECT", - "name": "user_courses_bool_exp", + "name": "user_articles_bool_exp", "ofType": null } } @@ -24430,7 +25142,7 @@ "deprecationReason": null, "description": "An array relationship", "isDeprecated": false, - "name": "user_courses", + "name": "user_articles", "type": { "kind": "NON_NULL", "name": null, @@ -24442,7 +25154,7 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "user_courses", + "name": "user_articles", "ofType": null } } @@ -24463,7 +25175,7 @@ "name": null, "ofType": { "kind": "ENUM", - "name": "user_courses_select_column", + "name": "user_articles_select_column", "ofType": null } } @@ -24501,7 +25213,7 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "user_courses_order_by", + "name": "user_articles_order_by", "ofType": null } } @@ -24513,7 +25225,7 @@ "name": "where", "type": { "kind": "INPUT_OBJECT", - "name": "user_courses_bool_exp", + "name": "user_articles_bool_exp", "ofType": null } } @@ -24521,13 +25233,13 @@ "deprecationReason": null, "description": "An aggregate relationship", "isDeprecated": false, - "name": "user_courses_aggregate", + "name": "user_articles_aggregate", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "OBJECT", - "name": "user_courses_aggregate", + "name": "user_articles_aggregate", "ofType": null } } @@ -24537,7 +25249,7 @@ { "defaultValue": null, "description": null, - "name": "course_id", + "name": "article_id", "type": { "kind": "NON_NULL", "name": null, @@ -24564,12 +25276,12 @@ } ], "deprecationReason": null, - "description": "fetch data from the table: \"user_courses\" using primary key columns", + "description": "fetch data from the table: \"user_articles\" using primary key columns", "isDeprecated": false, - "name": "user_courses_by_pk", + "name": "user_articles_by_pk", "type": { "kind": "OBJECT", - "name": "user_courses", + "name": "user_articles", "ofType": null } }, @@ -24601,7 +25313,7 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "user_courses_stream_cursor_input", + "name": "user_articles_stream_cursor_input", "ofType": null } } @@ -24613,15 +25325,15 @@ "name": "where", "type": { "kind": "INPUT_OBJECT", - "name": "user_courses_bool_exp", + "name": "user_articles_bool_exp", "ofType": null } } ], "deprecationReason": null, - "description": "fetch data from the table in a streaming manner: \"user_courses\"", + "description": "fetch data from the table in a streaming manner: \"user_articles\"", "isDeprecated": false, - "name": "user_courses_stream", + "name": "user_articles_stream", "type": { "kind": "NON_NULL", "name": null, @@ -24633,7 +25345,7 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "user_courses", + "name": "user_articles", "ofType": null } } @@ -24654,7 +25366,7 @@ "name": null, "ofType": { "kind": "ENUM", - "name": "users_select_column", + "name": "user_courses_select_column", "ofType": null } } @@ -24692,7 +25404,7 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "users_order_by", + "name": "user_courses_order_by", "ofType": null } } @@ -24704,7 +25416,7 @@ "name": "where", "type": { "kind": "INPUT_OBJECT", - "name": "users_bool_exp", + "name": "user_courses_bool_exp", "ofType": null } } @@ -24712,7 +25424,7 @@ "deprecationReason": null, "description": "An array relationship", "isDeprecated": false, - "name": "users", + "name": "user_courses", "type": { "kind": "NON_NULL", "name": null, @@ -24724,7 +25436,7 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "users", + "name": "user_courses", "ofType": null } } @@ -24745,7 +25457,7 @@ "name": null, "ofType": { "kind": "ENUM", - "name": "users_select_column", + "name": "user_courses_select_column", "ofType": null } } @@ -24783,7 +25495,7 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "users_order_by", + "name": "user_courses_order_by", "ofType": null } } @@ -24795,7 +25507,7 @@ "name": "where", "type": { "kind": "INPUT_OBJECT", - "name": "users_bool_exp", + "name": "user_courses_bool_exp", "ofType": null } } @@ -24803,13 +25515,13 @@ "deprecationReason": null, "description": "An aggregate relationship", "isDeprecated": false, - "name": "users_aggregate", + "name": "user_courses_aggregate", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "OBJECT", - "name": "users_aggregate", + "name": "user_courses_aggregate", "ofType": null } } @@ -24819,7 +25531,7 @@ { "defaultValue": null, "description": null, - "name": "id", + "name": "course_id", "type": { "kind": "NON_NULL", "name": null, @@ -24829,16 +25541,30 @@ "ofType": null } } - } - ], - "deprecationReason": null, - "description": "fetch data from the table: \"users\" using primary key columns", - "isDeprecated": false, - "name": "users_by_pk", - "type": { - "kind": "OBJECT", - "name": "users", - "ofType": null + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + } + ], + "deprecationReason": null, + "description": "fetch data from the table: \"user_courses\" using primary key columns", + "isDeprecated": false, + "name": "user_courses_by_pk", + "type": { + "kind": "OBJECT", + "name": "user_courses", + "ofType": null } }, { @@ -24869,7 +25595,7 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "users_stream_cursor_input", + "name": "user_courses_stream_cursor_input", "ofType": null } } @@ -24881,15 +25607,15 @@ "name": "where", "type": { "kind": "INPUT_OBJECT", - "name": "users_bool_exp", + "name": "user_courses_bool_exp", "ofType": null } } ], "deprecationReason": null, - "description": "fetch data from the table in a streaming manner: \"users\"", + "description": "fetch data from the table in a streaming manner: \"user_courses\"", "isDeprecated": false, - "name": "users_stream", + "name": "user_courses_stream", "type": { "kind": "NON_NULL", "name": null, @@ -24901,24 +25627,13 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "users", + "name": "user_courses", "ofType": null } } } } - } - ], - "inputFields": null, - "interfaces": [], - "kind": "OBJECT", - "name": "subscription_root", - "possibleTypes": null - }, - { - "description": "columns and relationships of \"tags\"", - "enumValues": null, - "fields": [ + }, { "args": [ { @@ -24933,7 +25648,7 @@ "name": null, "ofType": { "kind": "ENUM", - "name": "course_tags_select_column", + "name": "users_select_column", "ofType": null } } @@ -24971,7 +25686,7 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "course_tags_order_by", + "name": "users_order_by", "ofType": null } } @@ -24983,7 +25698,7 @@ "name": "where", "type": { "kind": "INPUT_OBJECT", - "name": "course_tags_bool_exp", + "name": "users_bool_exp", "ofType": null } } @@ -24991,7 +25706,7 @@ "deprecationReason": null, "description": "An array relationship", "isDeprecated": false, - "name": "course_tags", + "name": "users", "type": { "kind": "NON_NULL", "name": null, @@ -25003,7 +25718,7 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "course_tags", + "name": "users", "ofType": null } } @@ -25024,7 +25739,7 @@ "name": null, "ofType": { "kind": "ENUM", - "name": "course_tags_select_column", + "name": "users_select_column", "ofType": null } } @@ -25062,7 +25777,7 @@ "name": null, "ofType": { "kind": "INPUT_OBJECT", - "name": "course_tags_order_by", + "name": "users_order_by", "ofType": null } } @@ -25074,7 +25789,7 @@ "name": "where", "type": { "kind": "INPUT_OBJECT", - "name": "course_tags_bool_exp", + "name": "users_bool_exp", "ofType": null } } @@ -25082,78 +25797,93 @@ "deprecationReason": null, "description": "An aggregate relationship", "isDeprecated": false, - "name": "course_tags_aggregate", + "name": "users_aggregate", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "OBJECT", - "name": "course_tags_aggregate", - "ofType": null - } - } - }, - { - "args": [], - "deprecationReason": null, - "description": null, - "isDeprecated": false, - "name": "id", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Int", + "name": "users_aggregate", "ofType": null } } }, { - "args": [], - "deprecationReason": null, - "description": null, - "isDeprecated": false, - "name": "name", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null + "args": [ + { + "defaultValue": null, + "description": null, + "name": "id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } } - } - } - ], - "inputFields": null, - "interfaces": [], - "kind": "OBJECT", - "name": "tags", - "possibleTypes": null - }, - { - "description": "aggregated selection of \"tags\"", - "enumValues": null, - "fields": [ - { - "args": [], + ], "deprecationReason": null, - "description": null, + "description": "fetch data from the table: \"users\" using primary key columns", "isDeprecated": false, - "name": "aggregate", + "name": "users_by_pk", "type": { "kind": "OBJECT", - "name": "tags_aggregate_fields", + "name": "users", "ofType": null } }, { - "args": [], + "args": [ + { + "defaultValue": null, + "description": "maximum number of rows returned in a single batch", + "name": "batch_size", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + }, + { + "defaultValue": null, + "description": "cursor to stream the results returned by the query", + "name": "cursor", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "users_stream_cursor_input", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "filter the rows returned", + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "users_bool_exp", + "ofType": null + } + } + ], "deprecationReason": null, - "description": null, + "description": "fetch data from the table in a streaming manner: \"users\"", "isDeprecated": false, - "name": "nodes", + "name": "users_stream", "type": { "kind": "NON_NULL", "name": null, @@ -25165,7 +25895,7 @@ "name": null, "ofType": { "kind": "OBJECT", - "name": "tags", + "name": "users", "ofType": null } } @@ -25176,31 +25906,19 @@ "inputFields": null, "interfaces": [], "kind": "OBJECT", - "name": "tags_aggregate", + "name": "subscription_root", "possibleTypes": null }, { - "description": "aggregate fields of \"tags\"", + "description": "columns and relationships of \"tags\"", "enumValues": null, "fields": [ - { - "args": [], - "deprecationReason": null, - "description": null, - "isDeprecated": false, - "name": "avg", - "type": { - "kind": "OBJECT", - "name": "tags_avg_fields", - "ofType": null - } - }, { "args": [ { "defaultValue": null, - "description": null, - "name": "columns", + "description": "distinct select on columns", + "name": "distinct_on", "type": { "kind": "LIST", "name": null, @@ -25209,7 +25927,7 @@ "name": null, "ofType": { "kind": "ENUM", - "name": "tags_select_column", + "name": "course_tags_select_column", "ofType": null } } @@ -25217,27 +25935,303 @@ }, { "defaultValue": null, - "description": null, - "name": "distinct", + "description": "limit the number of rows returned", + "name": "limit", "type": { "kind": "SCALAR", - "name": "Boolean", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "skip the first n rows. Use only with order_by", + "name": "offset", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sort the rows by one or more columns", + "name": "order_by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "course_tags_order_by", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "filter the rows returned", + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "course_tags_bool_exp", "ofType": null } } ], "deprecationReason": null, - "description": null, + "description": "An array relationship", "isDeprecated": false, - "name": "count", + "name": "course_tags", "type": { "kind": "NON_NULL", "name": null, "ofType": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - } + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "course_tags", + "ofType": null + } + } + } + } + }, + { + "args": [ + { + "defaultValue": null, + "description": "distinct select on columns", + "name": "distinct_on", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "course_tags_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "limit the number of rows returned", + "name": "limit", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "skip the first n rows. Use only with order_by", + "name": "offset", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sort the rows by one or more columns", + "name": "order_by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "course_tags_order_by", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "filter the rows returned", + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "course_tags_bool_exp", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": "An aggregate relationship", + "isDeprecated": false, + "name": "course_tags_aggregate", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "course_tags_aggregate", + "ofType": null + } + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "name", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "tags", + "possibleTypes": null + }, + { + "description": "aggregated selection of \"tags\"", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "aggregate", + "type": { + "kind": "OBJECT", + "name": "tags_aggregate_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "nodes", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "tags", + "ofType": null + } + } + } + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "tags_aggregate", + "possibleTypes": null + }, + { + "description": "aggregate fields of \"tags\"", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "avg", + "type": { + "kind": "OBJECT", + "name": "tags_avg_fields", + "ofType": null + } + }, + { + "args": [ + { + "defaultValue": null, + "description": null, + "name": "columns", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "tags_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": null, + "name": "distinct", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "count", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } } }, { @@ -26246,67 +27240,2095 @@ } }, { - "defaultValue": null, + "defaultValue": null, + "description": null, + "name": "_is_null", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "_lt", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "_lte", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "_neq", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "_nin", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + } + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "timestamp_comparison_exp", + "possibleTypes": null + }, + { + "description": "columns and relationships of \"user_articles\"", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": "An object relationship", + "isDeprecated": false, + "name": "article", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "lms_articles", + "ofType": null + } + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "completed_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "created_at", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + } + }, + { + "args": [], + "deprecationReason": null, + "description": "An object relationship", + "isDeprecated": false, + "name": "user", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "users", + "ofType": null + } + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles", + "possibleTypes": null + }, + { + "description": "aggregated selection of \"user_articles\"", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "aggregate", + "type": { + "kind": "OBJECT", + "name": "user_articles_aggregate_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "nodes", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "user_articles", + "ofType": null + } + } + } + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_aggregate", + "possibleTypes": null + }, + { + "description": null, + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "count", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_aggregate_bool_exp_count", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_aggregate_bool_exp", + "possibleTypes": null + }, + { + "description": null, + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "arguments", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_articles_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": null, + "name": "distinct", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "filter", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "predicate", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "Int_comparison_exp", + "ofType": null + } + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_aggregate_bool_exp_count", + "possibleTypes": null + }, + { + "description": "aggregate fields of \"user_articles\"", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "avg", + "type": { + "kind": "OBJECT", + "name": "user_articles_avg_fields", + "ofType": null + } + }, + { + "args": [ + { + "defaultValue": null, + "description": null, + "name": "columns", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_articles_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": null, + "name": "distinct", + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "count", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "max", + "type": { + "kind": "OBJECT", + "name": "user_articles_max_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "min", + "type": { + "kind": "OBJECT", + "name": "user_articles_min_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "stddev", + "type": { + "kind": "OBJECT", + "name": "user_articles_stddev_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "stddev_pop", + "type": { + "kind": "OBJECT", + "name": "user_articles_stddev_pop_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "stddev_samp", + "type": { + "kind": "OBJECT", + "name": "user_articles_stddev_samp_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "sum", + "type": { + "kind": "OBJECT", + "name": "user_articles_sum_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "var_pop", + "type": { + "kind": "OBJECT", + "name": "user_articles_var_pop_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "var_samp", + "type": { + "kind": "OBJECT", + "name": "user_articles_var_samp_fields", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "variance", + "type": { + "kind": "OBJECT", + "name": "user_articles_variance_fields", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_aggregate_fields", + "possibleTypes": null + }, + { + "description": "order by aggregate values of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "avg", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_avg_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "count", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "max", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_max_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "min", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_min_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "stddev", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_stddev_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "stddev_pop", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_stddev_pop_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "stddev_samp", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_stddev_samp_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "sum", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_sum_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "var_pop", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_var_pop_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "var_samp", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_var_samp_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "variance", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_variance_order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_aggregate_order_by", + "possibleTypes": null + }, + { + "description": "input type for inserting array relation for remote table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "data", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_insert_input", + "ofType": null + } + } + } + } + }, + { + "defaultValue": null, + "description": "upsert condition", + "name": "on_conflict", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_on_conflict", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_arr_rel_insert_input", + "possibleTypes": null + }, + { + "description": "aggregate avg on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_avg_fields", + "possibleTypes": null + }, + { + "description": "order by avg() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_avg_order_by", + "possibleTypes": null + }, + { + "description": "Boolean expression to filter rows from the table \"user_articles\". All fields are combined with a logical 'AND'.", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "_and", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": null, + "name": "_not", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "_or", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": null, + "name": "article", + "type": { + "kind": "INPUT_OBJECT", + "name": "lms_articles_bool_exp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "INPUT_OBJECT", + "name": "Int_comparison_exp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "completed_at", + "type": { + "kind": "INPUT_OBJECT", + "name": "timestamp_comparison_exp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "created_at", + "type": { + "kind": "INPUT_OBJECT", + "name": "timestamp_comparison_exp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user", + "type": { + "kind": "INPUT_OBJECT", + "name": "users_bool_exp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "INPUT_OBJECT", + "name": "Int_comparison_exp", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "possibleTypes": null + }, + { + "description": "unique or primary key constraints on table \"user_articles\"", + "enumValues": [ + { + "deprecationReason": null, + "description": "unique or primary key constraint on columns \"user_id\", \"article_id\"", + "isDeprecated": false, + "name": "user_articles_pkey" + } + ], + "fields": null, + "inputFields": null, + "interfaces": null, + "kind": "ENUM", + "name": "user_articles_constraint", + "possibleTypes": null + }, + { + "description": "input type for incrementing numeric columns in table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_inc_input", + "possibleTypes": null + }, + { + "description": "input type for inserting data into table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article", + "type": { + "kind": "INPUT_OBJECT", + "name": "lms_articles_obj_rel_insert_input", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "completed_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "created_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user", + "type": { + "kind": "INPUT_OBJECT", + "name": "users_obj_rel_insert_input", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_insert_input", + "possibleTypes": null + }, + { + "description": "aggregate max on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "completed_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "created_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_max_fields", + "possibleTypes": null + }, + { + "description": "order by max() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "completed_at", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "created_at", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_max_order_by", + "possibleTypes": null + }, + { + "description": "aggregate min on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "completed_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "created_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_min_fields", + "possibleTypes": null + }, + { + "description": "order by min() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "completed_at", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "created_at", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_min_order_by", + "possibleTypes": null + }, + { + "description": "response of any mutation on the table \"user_articles\"", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": "number of rows affected by the mutation", + "isDeprecated": false, + "name": "affected_rows", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + }, + { + "args": [], + "deprecationReason": null, + "description": "data from the rows affected by the mutation", + "isDeprecated": false, + "name": "returning", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "user_articles", + "ofType": null + } + } + } + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_mutation_response", + "possibleTypes": null + }, + { + "description": "on_conflict condition type for table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "constraint", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_articles_constraint", + "ofType": null + } + } + }, + { + "defaultValue": "[]", + "description": null, + "name": "update_columns", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_articles_update_column", + "ofType": null + } + } + } + } + }, + { + "defaultValue": null, + "description": null, + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_on_conflict", + "possibleTypes": null + }, + { + "description": "Ordering options when selecting data from \"user_articles\".", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article", + "type": { + "kind": "INPUT_OBJECT", + "name": "lms_articles_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "completed_at", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "created_at", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user", + "type": { + "kind": "INPUT_OBJECT", + "name": "users_order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_order_by", + "possibleTypes": null + }, + { + "description": "primary key columns input for table: user_articles", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_pk_columns_input", + "possibleTypes": null + }, + { + "description": "select columns of table \"user_articles\"", + "enumValues": [ + { + "deprecationReason": null, + "description": "column name", + "isDeprecated": false, + "name": "article_id" + }, + { + "deprecationReason": null, + "description": "column name", + "isDeprecated": false, + "name": "completed_at" + }, + { + "deprecationReason": null, + "description": "column name", + "isDeprecated": false, + "name": "created_at" + }, + { + "deprecationReason": null, + "description": "column name", + "isDeprecated": false, + "name": "user_id" + } + ], + "fields": null, + "inputFields": null, + "interfaces": null, + "kind": "ENUM", + "name": "user_articles_select_column", + "possibleTypes": null + }, + { + "description": "input type for updating data in table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "completed_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "created_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_set_input", + "possibleTypes": null + }, + { + "description": "aggregate stddev on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_stddev_fields", + "possibleTypes": null + }, + { + "description": "order by stddev() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_stddev_order_by", + "possibleTypes": null + }, + { + "description": "aggregate stddev_pop on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_stddev_pop_fields", + "possibleTypes": null + }, + { + "description": "order by stddev_pop() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_stddev_pop_order_by", + "possibleTypes": null + }, + { + "description": "aggregate stddev_samp on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_stddev_samp_fields", + "possibleTypes": null + }, + { + "description": "order by stddev_samp() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_stddev_samp_order_by", + "possibleTypes": null + }, + { + "description": "Streaming cursor of the table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": "Stream column input with initial value", + "name": "initial_value", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_stream_cursor_value_input", + "ofType": null + } + } + }, + { + "defaultValue": null, + "description": "cursor ordering", + "name": "ordering", + "type": { + "kind": "ENUM", + "name": "cursor_ordering", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_stream_cursor_input", + "possibleTypes": null + }, + { + "description": "Initial value of the column from where the streaming should start", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "completed_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "created_at", + "type": { + "kind": "SCALAR", + "name": "timestamp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_stream_cursor_value_input", + "possibleTypes": null + }, + { + "description": "aggregate sum on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_sum_fields", + "possibleTypes": null + }, + { + "description": "order by sum() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_sum_order_by", + "possibleTypes": null + }, + { + "description": "update columns of table \"user_articles\"", + "enumValues": [ + { + "deprecationReason": null, + "description": "column name", + "isDeprecated": false, + "name": "article_id" + }, + { + "deprecationReason": null, + "description": "column name", + "isDeprecated": false, + "name": "completed_at" + }, + { + "deprecationReason": null, + "description": "column name", + "isDeprecated": false, + "name": "created_at" + }, + { + "deprecationReason": null, + "description": "column name", + "isDeprecated": false, + "name": "user_id" + } + ], + "fields": null, + "inputFields": null, + "interfaces": null, + "kind": "ENUM", + "name": "user_articles_update_column", + "possibleTypes": null + }, + { + "description": null, + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": "increments the numeric columns with given value of the filtered values", + "name": "_inc", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_inc_input", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sets the columns of the filtered rows to the given values", + "name": "_set", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_set_input", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "filter the rows which have to be updated", + "name": "where", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_updates", + "possibleTypes": null + }, + { + "description": "aggregate var_pop on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_var_pop_fields", + "possibleTypes": null + }, + { + "description": "order by var_pop() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_var_pop_order_by", + "possibleTypes": null + }, + { + "description": "aggregate var_samp on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "article_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + }, + { + "args": [], + "deprecationReason": null, + "description": null, + "isDeprecated": false, + "name": "user_id", + "type": { + "kind": "SCALAR", + "name": "Float", + "ofType": null + } + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_var_samp_fields", + "possibleTypes": null + }, + { + "description": "order by var_samp() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "article_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "user_id", + "type": { + "kind": "ENUM", + "name": "order_by", + "ofType": null + } + } + ], + "interfaces": null, + "kind": "INPUT_OBJECT", + "name": "user_articles_var_samp_order_by", + "possibleTypes": null + }, + { + "description": "aggregate variance on columns", + "enumValues": null, + "fields": [ + { + "args": [], + "deprecationReason": null, "description": null, - "name": "_is_null", + "isDeprecated": false, + "name": "article_id", "type": { "kind": "SCALAR", - "name": "Boolean", + "name": "Float", "ofType": null } }, { - "defaultValue": null, + "args": [], + "deprecationReason": null, "description": null, - "name": "_lt", + "isDeprecated": false, + "name": "user_id", "type": { "kind": "SCALAR", - "name": "timestamp", + "name": "Float", "ofType": null } - }, + } + ], + "inputFields": null, + "interfaces": [], + "kind": "OBJECT", + "name": "user_articles_variance_fields", + "possibleTypes": null + }, + { + "description": "order by variance() on columns of table \"user_articles\"", + "enumValues": null, + "fields": null, + "inputFields": [ { "defaultValue": null, "description": null, - "name": "_lte", + "name": "article_id", "type": { - "kind": "SCALAR", - "name": "timestamp", + "kind": "ENUM", + "name": "order_by", "ofType": null } }, { "defaultValue": null, "description": null, - "name": "_neq", + "name": "user_id", "type": { - "kind": "SCALAR", - "name": "timestamp", + "kind": "ENUM", + "name": "order_by", "ofType": null } - }, - { - "defaultValue": null, - "description": null, - "name": "_nin", - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "timestamp", - "ofType": null - } - } - } } ], "interfaces": null, "kind": "INPUT_OBJECT", - "name": "timestamp_comparison_exp", + "name": "user_articles_variance_order_by", "possibleTypes": null }, { @@ -28101,6 +31123,180 @@ "description": "columns and relationships of \"users\"", "enumValues": null, "fields": [ + { + "args": [ + { + "defaultValue": null, + "description": "distinct select on columns", + "name": "distinct_on", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_articles_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "limit the number of rows returned", + "name": "limit", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "skip the first n rows. Use only with order_by", + "name": "offset", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sort the rows by one or more columns", + "name": "order_by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_order_by", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "filter the rows returned", + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": "An array relationship", + "isDeprecated": false, + "name": "articles", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "user_articles", + "ofType": null + } + } + } + } + }, + { + "args": [ + { + "defaultValue": null, + "description": "distinct select on columns", + "name": "distinct_on", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "ENUM", + "name": "user_articles_select_column", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "limit the number of rows returned", + "name": "limit", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "skip the first n rows. Use only with order_by", + "name": "offset", + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + } + }, + { + "defaultValue": null, + "description": "sort the rows by one or more columns", + "name": "order_by", + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "user_articles_order_by", + "ofType": null + } + } + } + }, + { + "defaultValue": null, + "description": "filter the rows returned", + "name": "where", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + } + ], + "deprecationReason": null, + "description": "An aggregate relationship", + "isDeprecated": false, + "name": "articles_aggregate", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "OBJECT", + "name": "user_articles_aggregate", + "ofType": null + } + } + }, { "args": [], "deprecationReason": null, @@ -29180,6 +32376,26 @@ } } }, + { + "defaultValue": null, + "description": null, + "name": "articles", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_bool_exp", + "ofType": null + } + }, + { + "defaultValue": null, + "description": null, + "name": "articles_aggregate", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_aggregate_bool_exp", + "ofType": null + } + }, { "defaultValue": null, "description": null, @@ -29369,6 +32585,16 @@ "enumValues": null, "fields": null, "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "articles", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_arr_rel_insert_input", + "ofType": null + } + }, { "defaultValue": null, "description": null, @@ -30083,6 +33309,16 @@ "enumValues": null, "fields": null, "inputFields": [ + { + "defaultValue": null, + "description": null, + "name": "articles_aggregate", + "type": { + "kind": "INPUT_OBJECT", + "name": "user_articles_aggregate_order_by", + "ofType": null + } + }, { "defaultValue": null, "description": null, diff --git a/src/api/mod.rs b/src/api/mod.rs index 070ecfa..4f6c181 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -14,9 +14,10 @@ use yew::AttrValue; use crate::{ database_queries::{ - api_get_all_data, api_insert_article, api_insert_course, api_insert_course_articles, - api_insert_tag, ApiGetAllData, ApiInsertArticle, ApiInsertCourse, ApiInsertCourseArticles, - ApiInsertTag, + api_complete_user_article, api_get_all_data, api_insert_article, api_insert_course, + api_insert_course_articles, api_insert_tag, api_insert_user_article, + ApiCompleteUserArticle, ApiGetAllData, ApiInsertArticle, ApiInsertCourse, + ApiInsertCourseArticles, ApiInsertTag, ApiInsertUserArticle, }, errors::LmsError, types::{ApiAllData, Article, Course, Tag}, @@ -209,3 +210,35 @@ pub async fn set_course_articles( .await?; Ok(()) } + +pub async fn insert_user_article(token: AttrValue, user_id: i64, article_id: i64) -> Result<()> { + let variables = api_insert_user_article::Variables { + user_id, + article_id, + }; + let mutation = ApiInsertUserArticle::build_query(variables); + + SendToGraphql::new() + .authorization(token.as_str()) + .role(BBRole::Learner) + .json(mutation)? + .send::() + .await?; + + Ok(()) +} + +pub async fn completed_user_article(token: AttrValue, user_id: i64, article_id: i64) -> Result<()> { + let variables = api_complete_user_article::Variables { + user_id, + article_id, + }; + let mutation = ApiCompleteUserArticle::build_query(variables); + SendToGraphql::new() + .authorization(token.as_str()) + .role(BBRole::Learner) + .json(mutation)? + .send::() + .await?; + Ok(()) +} diff --git a/src/auth/mod.rs b/src/auth/mod.rs index abd443c..0f3d5ac 100644 --- a/src/auth/mod.rs +++ b/src/auth/mod.rs @@ -5,7 +5,7 @@ use rand::{distributions::Alphanumeric, thread_rng, Rng}; use yew::AttrValue; static STATE_COOKIE_KEY: &str = "auth_state"; -static STATE_COOKIE_MAX_LIFE: u32 = 60 * 5; +static STATE_COOKIE_MAX_LIFE: u32 = 60 * 60; static AUTH0_DOMAIN: &str = dotenv!("AUTH0_DOMAIN"); static AUTH0_CLIENT_ID: &str = dotenv!("AUTH0_CLIENT_ID"); static AUTH_REDIRECT_URI: &str = dotenv!("AUTH_REDIRECT_URI"); diff --git a/src/components/course_nav.rs b/src/components/course_nav.rs index dd59a3b..e7a7bed 100644 --- a/src/components/course_nav.rs +++ b/src/components/course_nav.rs @@ -27,8 +27,15 @@ pub fn component(props: &Props) -> Html { let is_owned = store.own_course(course_id); let mut article_builder = BBCourseNavArticleBuilder::new() .title(article.title.clone()) + .id(article.id.to_string()) .preview(if is_owned { false } else { is_preview }); + article_builder = if let Some(db_user) = &store.db_user { + article_builder.completed(db_user.has_completed_article(article.id)) + } else { + article_builder + }; + article_builder = if is_preview || is_owned { article_builder.to(Routes::CourseAccessArticle { course_id: props.course_id, diff --git a/src/components/mod.rs b/src/components/mod.rs index d958dde..a6f53c4 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -1,2 +1,3 @@ pub mod alert; pub mod course_nav; +pub mod next_article; diff --git a/src/components/next_article.rs b/src/components/next_article.rs new file mode 100644 index 0000000..af4f20d --- /dev/null +++ b/src/components/next_article.rs @@ -0,0 +1,57 @@ +#![allow(non_camel_case_types)] +use ycl::elements::{ + button::{BBButton, BBButtonStyle}, + internal_link::BBInternalLink, +}; +use yew::prelude::*; +use yewdux::prelude::use_store; + +use crate::{ + router::Routes, + stores::main_store::MainStore, + types::{Article, Course}, +}; + +#[derive(Properties, PartialEq, Debug)] +pub struct Props { + pub article_id: i64, + pub course_id: i64, + #[prop_or_default()] + pub onclick: Callback, +} + +#[function_component(NextArticle)] +pub fn component(props: &Props) -> Html { + let (store, _dispatch) = use_store::(); + let Some(course) = store.courses.get(&props.course_id) else { return html! {} }; + let props_onclick = props.onclick.clone(); + let article_id = props.article_id; + let onclick = Callback::from(move |_| { + props_onclick.emit(article_id); + }); + let Some(next_article) = next_article(course, props.article_id, store.own_course(props.course_id)) else { return html! { + {"Complete Article"} + } }; + let title = format!("Complete and goto next article: {}", &next_article.title); + + html! { + to={Routes::CourseAccessArticle { course_id: props.course_id, article_id: next_article.id }} button={true} {onclick}>{title}> + } +} + +fn next_article(course: &Course, article_id: i64, own_course: bool) -> Option<&Article> { + let (current_index, _current_article) = course + .articles + .iter() + .enumerate() + .find(move |(_, article)| article.id == article_id)?; + + if own_course { + course.articles.get(current_index + 1) + } else { + course + .articles + .iter() + .find(move |article| article.id > article_id && article.preview.unwrap_or_default()) + } +} diff --git a/src/database_queries.rs b/src/database_queries.rs index 3ca2b2d..8da8074 100644 --- a/src/database_queries.rs +++ b/src/database_queries.rs @@ -46,3 +46,19 @@ pub struct ApiInsertArticle; response_derives = "Debug" )] pub struct ApiInsertCourseArticles; + +#[derive(GraphQLQuery)] +#[graphql( + schema_path = "database/schema.json", + query_path = "database/mutations/api_insert_user_article.graphql", + response_derives = "Debug" +)] +pub struct ApiInsertUserArticle; + +#[derive(GraphQLQuery)] +#[graphql( + schema_path = "database/schema.json", + query_path = "database/mutations/api_complete_user_article.graphql", + response_derives = "Debug" +)] +pub struct ApiCompleteUserArticle; diff --git a/src/pages/course_access_article.rs b/src/pages/course_access_article.rs index a580fa2..13a882f 100644 --- a/src/pages/course_access_article.rs +++ b/src/pages/course_access_article.rs @@ -10,10 +10,16 @@ use ycl::{ modules::course_content::BBCourseContent, }; use yew::prelude::*; + use yew_router::prelude::use_navigator; use yewdux::prelude::use_store; -use crate::{components::course_nav::CourseNav, router::Routes, stores::main_store::MainStore}; +use crate::{ + api, + components::{course_nav::CourseNav, next_article::NextArticle}, + router::Routes, + stores::main_store::{self, MainStore}, +}; #[derive(Properties, PartialEq)] pub struct Props { @@ -23,9 +29,48 @@ pub struct Props { #[function_component(CourseAccessArticle)] pub fn component(props: &Props) -> Html { - let (store, _dispatch) = use_store::(); + let (store, dispatch) = use_store::(); let navigation = use_navigator().unwrap(); + { + let dispatch = dispatch.clone(); + let article_id = props.article_id; + let store = store.clone(); + + use_effect(move || { + let return_closure = || {}; + let dispatch = dispatch.clone(); + let Some(db_user) = &store.db_user else { return return_closure }; + + if !db_user.has_started_article(article_id) { + main_store::mark_article_opened(dispatch.clone(), article_id); + + { + let store = store.clone(); + let user_id = db_user.id; + + wasm_bindgen_futures::spawn_local(async move { + let Some(token) = store.user.token.clone() else { return }; + if let Err(error) = + api::insert_user_article(token, user_id, article_id).await + { + gloo::console::error!( + "Error inserting user article:", + error.to_string() + ); + main_store::error_alert( + dispatch, + "There was an error marking the article as started", + ); + } + }); + } + } + + return_closure + }) + }; + if let Some(course) = store.courses.get(&props.course_id) { let article_id = props.article_id; let course_id = course.id; @@ -44,6 +89,47 @@ pub fn component(props: &Props) -> Html { .get(&course.id) .cloned() .unwrap_or_default(); + + let next_article_onclick = { + let store = store.clone(); + Callback::from(move |completed_article_id: i64| { + let Some(user) = &store.db_user else { + gloo::console::error!("missing user so cannot mark article read"); + return + }; + let Some(token) = store.user.token.clone() else { + gloo::console::error!("missing token so cannot mark article completed"); + return + }; + let user_id = user.id; + let dispatch = dispatch.clone(); + + wasm_bindgen_futures::spawn_local(async move { + match api::completed_user_article(token.clone(), user_id, completed_article_id) + .await + { + Ok(_) => { + // TODO upsert the completed article in the case it doesn't exist yet: https://hasura.io/docs/latest/mutations/postgres/upsert/ + main_store::mark_article_completed( + dispatch.clone(), + completed_article_id, + ); + } + Err(error) => { + gloo::console::error!( + "Error completing user article", + error.to_string() + ); + main_store::error_alert( + dispatch.clone(), + "There was an error marking the article as completed", + ); + } + } + }); + }) + }; + if let Some(article) = course .articles .iter() @@ -65,6 +151,7 @@ pub fn component(props: &Props) -> Html { course={article.content.clone().unwrap_or_default()} {onclick_purchase} /> + diff --git a/src/stores/main_store.rs b/src/stores/main_store.rs index 61f8815..955b01b 100644 --- a/src/stores/main_store.rs +++ b/src/stores/main_store.rs @@ -323,3 +323,17 @@ pub async fn save_course_articles(dispatch: Dispatch, course_id: i64) }) .await } + +pub fn mark_article_completed(dispatch: Dispatch, article_id: i64) { + dispatch.reduce_mut(|store| { + let Some(user) = &mut store.db_user else { return }; + user.complete_article(article_id); + }) +} + +pub fn mark_article_opened(dispatch: Dispatch, article_id: i64) { + dispatch.reduce_mut(move |store| { + let Some(db_user) = &mut store.db_user else { return }; + db_user.start_article(article_id); + }); +} diff --git a/src/types.rs b/src/types.rs index bd76e4f..71d02e2 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,7 +1,8 @@ use std::collections::HashMap; use crate::database_queries::{ - api_get_all_data, api_insert_article, api_insert_course, api_insert_tag, + api_get_all_data::{self, ApiGetAllDataUsersArticles}, + api_insert_article, api_insert_course, api_insert_tag, }; use serde::{Deserialize, Serialize}; use ycl::{elements::icon::BBIconType, foundations::roles::BBRole, modules::banner::BBBannerType}; @@ -218,6 +219,37 @@ pub struct ApiAllData { pub struct DbUser { pub id: i64, pub purchased_courses: Vec, + pub articles: Vec, +} + +impl DbUser { + pub fn has_started_article(&self, article_id: i64) -> bool { + self.articles + .iter() + .any(|article| article.article_id == article_id) + } + + pub fn has_completed_article(&self, article_id: i64) -> bool { + let Some(article) = self.articles.iter().find(|article| article.article_id == article_id) else { return false }; + + article.completed_at.is_some() + } + + pub fn complete_article(&mut self, article_id: i64) { + for article in self.articles.iter_mut() { + if article.article_id == article_id { + // This should be a date, but for right now we are being lazy and just setting it to be some since we don't care (at this moment) about the content, just that something exists + article.completed_at = Some(Default::default()); + } + } + } + + pub fn start_article(&mut self, article_id: i64) { + self.articles.push(UserArticle { + article_id, + completed_at: None, + }); + } } impl From<&api_get_all_data::ApiGetAllDataUsers> for DbUser { @@ -229,6 +261,22 @@ impl From<&api_get_all_data::ApiGetAllDataUsers> for DbUser { .iter() .map(|course| course.courses.id) .collect(), + articles: value.articles.iter().map(Into::into).collect(), + } + } +} + +#[derive(Default, Clone, PartialEq)] +pub struct UserArticle { + pub article_id: i64, + pub completed_at: Option, +} + +impl From<&ApiGetAllDataUsersArticles> for UserArticle { + fn from(value: &ApiGetAllDataUsersArticles) -> Self { + Self { + article_id: value.article_id, + completed_at: value.completed_at.clone().map(Into::into), } } }