diff --git a/examples/ckan-example/.env b/examples/ckan-example/.env new file mode 100644 index 00000000..ae822d42 --- /dev/null +++ b/examples/ckan-example/.env @@ -0,0 +1 @@ +DMS=https://demo.dev.datopian.com diff --git a/examples/ckan-example/.eslintrc.json b/examples/ckan-example/.eslintrc.json new file mode 100644 index 00000000..835f29eb --- /dev/null +++ b/examples/ckan-example/.eslintrc.json @@ -0,0 +1,34 @@ +{ + "extends": [ + "plugin:@nrwl/nx/react-typescript", + "next", + "next/core-web-vitals", + "../../.eslintrc.json" + ], + "ignorePatterns": ["!**/*", ".next/**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": { + "@next/next/no-html-link-for-pages": [ + "error", + "examples/ckan-example/pages" + ] + } + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ], + "rules": { + "@next/next/no-html-link-for-pages": "off" + }, + "env": { + "jest": true + } +} diff --git a/examples/ckan-example/README.md b/examples/ckan-example/README.md new file mode 100644 index 00000000..f329bd6f --- /dev/null +++ b/examples/ckan-example/README.md @@ -0,0 +1,17 @@ +This is a repo intended to serve as an example of a data catalog that get its data from a CKAN Instance. + +- Creating a new file inside o `examples` with `create-next-app` like so: +``` +npx create-next-app --example https://github.com/datopian/portaljs/tree/main/ --example-path examples/ckan-example +``` +- Inside `` go to the `project.json` file and replace all instances of `ckan-example` with `` +- Set the `DMS` env variable to the Url of the CKAN Instance Ex: `export DMS=https://demo.dev.datopian.com` +- Run the app using: +``` +nx serve +``` +Congratulations, you now have something similar to this running on `http://localhost:4200` +![](https://media.discordapp.net/attachments/1069718983604977754/1098252297726865408/image.png?width=853&height=461) +If yo go to any one of those pages by clicking on `More info` you will see something similar to this +![](https://media.discordapp.net/attachments/1069718983604977754/1098252298074988595/image.png?width=853&height=461) + diff --git a/examples/ckan-example/index.d.ts b/examples/ckan-example/index.d.ts new file mode 100644 index 00000000..7ba08fa1 --- /dev/null +++ b/examples/ckan-example/index.d.ts @@ -0,0 +1,6 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +declare module '*.svg' { + const content: any; + export const ReactComponent: any; + export default content; +} diff --git a/examples/ckan-example/jest.config.ts b/examples/ckan-example/jest.config.ts new file mode 100644 index 00000000..ee098cb6 --- /dev/null +++ b/examples/ckan-example/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'ckan-example', + preset: '../../jest.preset.js', + transform: { + '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest', + '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/next/babel'] }], + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../coverage/examples/ckan-example', +}; diff --git a/examples/ckan-example/next-env.d.ts b/examples/ckan-example/next-env.d.ts new file mode 100644 index 00000000..4f11a03d --- /dev/null +++ b/examples/ckan-example/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/examples/ckan-example/next.config.js b/examples/ckan-example/next.config.js new file mode 100644 index 00000000..38dee978 --- /dev/null +++ b/examples/ckan-example/next.config.js @@ -0,0 +1,28 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { withNx } = require('@nrwl/next/plugins/with-nx'); + +/** + * @type {import('@nrwl/next/plugins/with-nx').WithNxOptions} + **/ +const nextConfig = { + publicRuntimeConfig: { + DMS: process.env.DMS ? process.env.DMS : '', + }, + async rewrites() { + return { + beforeFiles: [ + { + source: '/@:org/:project*', + destination: '/@org/:org/:project*', + }, + ], + }; + }, + nx: { + // Set this to true if you would like to use SVGR + // See: https://github.com/gregberge/svgr + svgr: false, + }, +}; + +module.exports = withNx(nextConfig); diff --git a/examples/ckan-example/pages/@org/[org]/[dataset]/index.tsx b/examples/ckan-example/pages/@org/[org]/[dataset]/index.tsx new file mode 100644 index 00000000..d233e7a2 --- /dev/null +++ b/examples/ckan-example/pages/@org/[org]/[dataset]/index.tsx @@ -0,0 +1,188 @@ +import { GetServerSideProps } from 'next'; +import getConfig from 'next/config'; +import React from 'react'; +import { + CalendarIcon, + CloudArrowUpIcon, + FolderOpenIcon, + LockClosedIcon, + MapPinIcon, + PaperClipIcon, + ServerIcon, + UserIcon, +} from '@heroicons/react/20/solid'; + +const dms = getConfig().publicRuntimeConfig.DMS; + +const formatter = new Intl.DateTimeFormat('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + timeZone: 'UTC', +}); + +export const getServerSideProps: GetServerSideProps = async (context) => { + const { dataset } = context.query; + const response = await fetch( + `${dms}/api/3/action/package_show?id=${dataset}` + ); + const _dataset = await response.json(); + return { + props: { + dataset: _dataset.result, + }, + }; +}; + +const positions = [ + { + id: 1, + title: 'Back End Developer', + type: 'Full-time', + location: 'Remote', + department: 'Engineering', + closeDate: '2020-01-07', + closeDateFull: 'January 7, 2020', + }, + { + id: 2, + title: 'Front End Developer', + type: 'Full-time', + location: 'Remote', + department: 'Engineering', + closeDate: '2020-01-07', + closeDateFull: 'January 7, 2020', + }, + { + id: 3, + title: 'User Interface Designer', + type: 'Full-time', + location: 'Remote', + department: 'Design', + closeDate: '2020-01-14', + closeDateFull: 'January 14, 2020', + }, +]; + +export default function DatasetPage({ dataset }) { + return ( +
+
+
+
+
+

+ {dataset.organization.title + ? dataset.organization.title + : dataset.organization.name} +

+

+ {dataset.title ? dataset.title : dataset.name} +

+

+ {dataset.notes ? dataset.notes : 'No description'} +

+
+
+ {dataset.tags.length > 0 && ( +
+
+ Tags +
+
+ {dataset.tags.map((tag) => tag.display_name).join(', ')} +
+
+ )} + {dataset.url && ( +
+
+ Url +
+
+ {dataset.url} +
+
+ )} +
+
+ Created +
+
+ {formatter.format(new Date(dataset.metadata_created))} +
+
+
+
+ Modified +
+
+ {formatter.format(new Date(dataset.metadata_modified))} +
+
+
+
+
+
+ +
+
+
+ ); +} diff --git a/examples/ckan-example/pages/_app.tsx b/examples/ckan-example/pages/_app.tsx new file mode 100644 index 00000000..4c34f72b --- /dev/null +++ b/examples/ckan-example/pages/_app.tsx @@ -0,0 +1,18 @@ +import { AppProps } from 'next/app'; +import Head from 'next/head'; +import './styles.css' + +function CustomApp({ Component, pageProps }: AppProps) { + return ( + <> + + Welcome to ckan-example! + +
+ +
+ + ); +} + +export default CustomApp; diff --git a/examples/ckan-example/pages/index.tsx b/examples/ckan-example/pages/index.tsx new file mode 100644 index 00000000..9cc17131 --- /dev/null +++ b/examples/ckan-example/pages/index.tsx @@ -0,0 +1,114 @@ +import getConfig from 'next/config'; +import styles from './index.module.css'; + +const dms = getConfig().publicRuntimeConfig.DMS + +const formatter = new Intl.DateTimeFormat('en-US', { + year: 'numeric', + month: 'long', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + timeZone: 'UTC', +}); + + +export async function getServerSideProps() { + const response = await fetch(`${dms}/api/3/action/package_search`) + const datasets = await response.json() + const datasetsWithDetails = await Promise.all(datasets.result.results.map(async (dataset) => { + const response = await fetch(`${dms}/api/3/action/package_show?id=` + dataset.name) + const json = await response.json() + return json.result + })) + + return { + props: { + datasets: datasetsWithDetails + } + } +} + +export function Index({ datasets }) { + return ( +
+
+

+ My Datasets +

+

+ Here is a list of all my datasets for easy access and sharing, they + are all available in the following{' '} + + CKAN Instance + +

+
+
+
+ + + + + + + + + + + {datasets.map((dataset) => ( + + + + + + + ))} + +
+ Title + + Description + + Last updated +
+ {dataset.title} + + {dataset.notes} + + {formatter.format( + new Date(dataset.metadata_modified) + )} + + + More info + +
+
+
+
+
+
+ ); +} + +export default Index; diff --git a/examples/ckan-example/pages/styles.css b/examples/ckan-example/pages/styles.css new file mode 100644 index 00000000..b5c61c95 --- /dev/null +++ b/examples/ckan-example/pages/styles.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/examples/ckan-example/postcss.config.js b/examples/ckan-example/postcss.config.js new file mode 100644 index 00000000..c72626d6 --- /dev/null +++ b/examples/ckan-example/postcss.config.js @@ -0,0 +1,15 @@ +const { join } = require('path'); + +// Note: If you use library-specific PostCSS/Tailwind configuration then you should remove the `postcssConfig` build +// option from your application's configuration (i.e. project.json). +// +// See: https://nx.dev/guides/using-tailwind-css-in-react#step-4:-applying-configuration-to-libraries + +module.exports = { + plugins: { + tailwindcss: { + config: join(__dirname, 'tailwind.config.js'), + }, + autoprefixer: {}, + }, +}; diff --git a/examples/ckan-example/project.json b/examples/ckan-example/project.json new file mode 100644 index 00000000..a63f1f64 --- /dev/null +++ b/examples/ckan-example/project.json @@ -0,0 +1,69 @@ +{ + "name": "ckan-example", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "examples/ckan-example", + "projectType": "application", + "targets": { + "build": { + "executor": "@nrwl/next:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "root": "examples/ckan-example", + "outputPath": "dist/examples/ckan-example" + }, + "configurations": { + "development": { + "outputPath": "examples/ckan-example" + }, + "production": {} + } + }, + "serve": { + "executor": "@nrwl/next:server", + "defaultConfiguration": "development", + "options": { + "buildTarget": "ckan-example:build", + "dev": true + }, + "configurations": { + "development": { + "buildTarget": "ckan-example:build:development", + "dev": true + }, + "production": { + "buildTarget": "ckan-example:build:production", + "dev": false + } + } + }, + "export": { + "executor": "@nrwl/next:export", + "options": { + "buildTarget": "ckan-example:build:production" + } + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "examples/ckan-example/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + }, + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["examples/ckan-example/**/*.{ts,tsx,js,jsx}"] + } + } + }, + "tags": [] +} diff --git a/examples/ckan-example/public/.gitkeep b/examples/ckan-example/public/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/examples/ckan-example/specs/index.spec.tsx b/examples/ckan-example/specs/index.spec.tsx new file mode 100644 index 00000000..42c94022 --- /dev/null +++ b/examples/ckan-example/specs/index.spec.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { render } from '@testing-library/react'; + +import Index from '../pages/index'; + +describe('Index', () => { + it('should render successfully', () => { + const { baseElement } = render(); + expect(baseElement).toBeTruthy(); + }); +}); diff --git a/examples/ckan-example/tailwind.config.js b/examples/ckan-example/tailwind.config.js new file mode 100644 index 00000000..d00839f6 --- /dev/null +++ b/examples/ckan-example/tailwind.config.js @@ -0,0 +1,17 @@ +const { createGlobPatternsForDependencies } = require('@nrwl/react/tailwind'); +const { join } = require('path'); + +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + join( + __dirname, + '{src,pages,components}/**/*!(*.stories|*.spec).{ts,tsx,html}' + ), + ...createGlobPatternsForDependencies(__dirname), + ], + theme: { + extend: {}, + }, + plugins: [], +}; diff --git a/examples/ckan-example/tsconfig.json b/examples/ckan-example/tsconfig.json new file mode 100644 index 00000000..7a9f3ecf --- /dev/null +++ b/examples/ckan-example/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "jsx": "preserve", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "resolveJsonModule": true, + "isolatedModules": true, + "incremental": true, + "types": ["jest", "node"] + }, + "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "next-env.d.ts"], + "exclude": [ + "node_modules", + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts" + ] +} diff --git a/examples/ckan-example/tsconfig.spec.json b/examples/ckan-example/tsconfig.spec.json new file mode 100644 index 00000000..214b2cc2 --- /dev/null +++ b/examples/ckan-example/tsconfig.spec.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"], + "jsx": "react" + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/examples/simple-example-e2e/.eslintrc.json b/examples/simple-example-e2e/.eslintrc.json deleted file mode 100644 index 696cb8b1..00000000 --- a/examples/simple-example-e2e/.eslintrc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": ["plugin:cypress/recommended", "../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - } - ] -} diff --git a/examples/simple-example-e2e/cypress.config.ts b/examples/simple-example-e2e/cypress.config.ts deleted file mode 100644 index 22f7c84e..00000000 --- a/examples/simple-example-e2e/cypress.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { defineConfig } from 'cypress'; -import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset'; - -export default defineConfig({ - e2e: nxE2EPreset(__dirname), -}); diff --git a/examples/simple-example-e2e/project.json b/examples/simple-example-e2e/project.json deleted file mode 100644 index d56a41ae..00000000 --- a/examples/simple-example-e2e/project.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "simple-example-e2e", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "examples/simple-example-e2e/src", - "projectType": "application", - "targets": { - "e2e": { - "executor": "@nrwl/cypress:cypress", - "options": { - "cypressConfig": "examples/simple-example-e2e/cypress.config.ts", - "devServerTarget": "simple-example:serve:development", - "testingType": "e2e" - }, - "configurations": { - "production": { - "devServerTarget": "simple-example:serve:production" - } - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["examples/simple-example-e2e/**/*.{js,ts}"] - } - } - }, - "tags": [], - "implicitDependencies": ["simple-example"] -} diff --git a/examples/simple-example-e2e/src/e2e/app.cy.ts b/examples/simple-example-e2e/src/e2e/app.cy.ts deleted file mode 100644 index 8197f9b3..00000000 --- a/examples/simple-example-e2e/src/e2e/app.cy.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getGreeting } from '../support/app.po'; - -describe('simple-example', () => { - beforeEach(() => cy.visit('/')); - - it('should display welcome message', () => { - // Custom command example, see `../support/commands.ts` file - cy.login('my-email@something.com', 'myPassword'); - - // Function helper example, see `../support/app.po.ts` file - getGreeting().contains('Welcome simple-example'); - }); -}); diff --git a/examples/simple-example-e2e/src/fixtures/example.json b/examples/simple-example-e2e/src/fixtures/example.json deleted file mode 100644 index 294cbed6..00000000 --- a/examples/simple-example-e2e/src/fixtures/example.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io" -} diff --git a/examples/simple-example-e2e/src/support/app.po.ts b/examples/simple-example-e2e/src/support/app.po.ts deleted file mode 100644 index 32934246..00000000 --- a/examples/simple-example-e2e/src/support/app.po.ts +++ /dev/null @@ -1 +0,0 @@ -export const getGreeting = () => cy.get('h1'); diff --git a/examples/simple-example-e2e/src/support/commands.ts b/examples/simple-example-e2e/src/support/commands.ts deleted file mode 100644 index 310f1fa0..00000000 --- a/examples/simple-example-e2e/src/support/commands.ts +++ /dev/null @@ -1,33 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -// eslint-disable-next-line @typescript-eslint/no-namespace -declare namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - } -} -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/examples/simple-example-e2e/src/support/e2e.ts b/examples/simple-example-e2e/src/support/e2e.ts deleted file mode 100644 index 3d469a6b..00000000 --- a/examples/simple-example-e2e/src/support/e2e.ts +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands'; diff --git a/examples/simple-example-e2e/tsconfig.json b/examples/simple-example-e2e/tsconfig.json deleted file mode 100644 index cc509a73..00000000 --- a/examples/simple-example-e2e/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "sourceMap": false, - "outDir": "../../dist/out-tsc", - "allowJs": true, - "types": ["cypress", "node"] - }, - "include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"] -} diff --git a/examples/simple-example/README.md b/examples/simple-example/README.md index fb98d0fb..733b798b 100644 --- a/examples/simple-example/README.md +++ b/examples/simple-example/README.md @@ -1,4 +1,4 @@ -This is a repo intended to serve as an simple-example of a data catalog that get its data from a series of github-repos, you can init an example just like this one by. +This is a repo intended to serve as a simple example of a data catalog that get its data from a series of github repos, you can init an example just like this one by. - Creating a new file inside o `examples` with `create-next-app` like so: ```