-
-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Assets: rewrite to TS and plugin system
- Loading branch information
Showing
40 changed files
with
2,424 additions
and
1,307 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,116 +6,103 @@ Table of contents | |
|
||
# Assets | ||
|
||
Datagrid needs for its precise functionality some third party scripts and styles. Install all required assets with NPM. | ||
There are prepare JS/TS and CSS files for precise functionality. The best way is to use some frontend bundler, for example [Vite](https://vitejs.dev). | ||
|
||
**CSS (external)** | ||
## Installation | ||
|
||
- bootstrap 5 | ||
- bootstrap datepicker | ||
- bootstrap select | ||
|
||
**CSS** | ||
|
||
- datagrid.css | ||
- datagrid-spinners.css | ||
|
||
**JS (external)** | ||
|
||
- jquery | ||
- nette forms | ||
- nette ajax / naja | ||
- bootstrap | ||
- bootstrap datepicker | ||
- bootstrap select | ||
|
||
**JS** | ||
|
||
- datagrid.js | ||
- datagrid-instant-url-refresh.js | ||
- datagrid-spinners.js | ||
|
||
**Icons** | ||
|
||
You will probably want to use some icon font, but that is in your command. | ||
On this project website we use font awesome (you can change the icon prefix by setting new value to static property `Datagrid::$iconPrefix = 'fa fa-';`). | ||
|
||
**Spinners** | ||
|
||
As you can see, there is also a `datagrid-spinners.js` script in a datagrid repository. If you include this file within you project layout, there are some actions, that will show spinner/some other animation when waiting for ajax response. Actions, that has somehow animated spinner: | ||
|
||
- Group actions | ||
- Pagination | ||
- Changing items per page | ||
- Toggling item detail - loading the detail for the first time | ||
|
||
## NPM | ||
|
||
``` | ||
npm install --save ublaboo-datagrid | ||
``` | ||
|
||
package.json: | ||
You need to install datagrid's assets. For example this way. | ||
|
||
```json | ||
{ | ||
"dependencies": { | ||
"bootstrap-datepicker": "^1.9", | ||
"bootstrap-select": "^1.14-beta2", | ||
"bootstrap": "^5.0.0", | ||
"happy-inputs": "^2.0", | ||
"jquery": "^3.4.1", | ||
"jquery-ui-sortable": "^1.0", | ||
"nette-forms": "^3.0", | ||
"nette.ajax.js": "^2.3", | ||
"popper.js": "^1.14.7", | ||
"ublaboo-datagrid": "^6.9" | ||
} | ||
"dependencies": { | ||
"@contributte/datagrid": "git+ssh://[email protected]:contributte/datagrid.git#next" | ||
} | ||
} | ||
``` | ||
|
||
## Example html when not using NPM | ||
|
||
```html | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.css"> | ||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/src/happy.css"> | ||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-datepicker.css"> | ||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/assets/datagrid.css"> | ||
|
||
<!-- Use this css for ajax spinners --> | ||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/assets/datagrid-spinners.css"> | ||
|
||
<!-- Include this css when using FilterMultiSelect (https://developer.snapappointments.com/bootstrap-select/) --> | ||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-select.css"> | ||
## | ||
|
||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css" integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous"> | ||
</head> | ||
## Demo | ||
|
||
<body> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src/nomodule-es5-fallback.js"></script> | ||
<script> | ||
var happy = new Happy; | ||
Full example of using bundler. | ||
|
||
happy.init(); | ||
</script> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap-datepicker.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/jquery-ui.min.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/nette.ajax.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/assets/datagrid.js"></script> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src/assets/netteForms.min.js"></script> | ||
**package.json** | ||
|
||
<!-- It is recommended to include this JS file with just a few bits. It refreshes URL on non ajax request --> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/assets/datagrid-instant-url-refresh.js"></script> | ||
|
||
<!-- Use this little extension for ajax spinners --> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/assets/datagrid-spinners.js"></script> | ||
```json | ||
{ | ||
"dependencies": { | ||
"@contributte/datagrid": "git+ssh://[email protected]:contributte/datagrid.git#next", | ||
"@fortawesome/fontawesome-free": "^6.3.0", | ||
"bootstrap": "^5.3.0-alpha3", | ||
"naja": "^2.5.0", | ||
"nette-forms": "^3.3.1", | ||
"prismjs": "^1.29.0", | ||
"sortablejs": "^1.15.0", | ||
"tom-select": "^2.2.2", | ||
"vanillajs-datepicker": "^1.3.1" | ||
}, | ||
"devDependencies": { | ||
"@types/bootstrap-select": "^1.13.4", | ||
"@types/jquery": "^3.5.16", | ||
"@types/jqueryui": "^1.12.16", | ||
"@types/sortablejs": "^1.15.1", | ||
"@types/vanillajs-datepicker": "^1.2.1", | ||
"autoprefixer": "^10.4.0", | ||
"typescript": "^4.9.5", | ||
"vite": "^2.6.10" | ||
}, | ||
"scripts": { | ||
"watch": "vite build --watch --mode=development", | ||
"build": "vite build --mode=production" | ||
} | ||
} | ||
``` | ||
|
||
<!-- Include bootstrap-select.js when using FilterMultiSelect (https://developer.snapappointments.com/bootstrap-select/) --> | ||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap-select.js"></script> | ||
</body> | ||
</html> | ||
**vite.config.js** | ||
|
||
```js | ||
import { defineConfig } from 'vite'; | ||
import { resolve } from 'path'; | ||
|
||
export default defineConfig(({ mode }) => { | ||
const DEV = mode === 'development'; | ||
|
||
return { | ||
publicDir: './assets/public', | ||
resolve: { | ||
alias: { | ||
'@': resolve(__dirname, 'assets/js'), | ||
'~': resolve(__dirname, 'node_modules'), | ||
}, | ||
}, | ||
base: '/dist/', | ||
server: { | ||
open: false, | ||
hmr: false, | ||
}, | ||
css: { | ||
postcss: [ | ||
"autoprefixer" | ||
] | ||
}, | ||
build: { | ||
manifest: true, | ||
assetsDir: '', | ||
outDir: './www/dist/', | ||
emptyOutDir: true, | ||
minify: DEV ? false : 'esbuild', | ||
rollupOptions: { | ||
output: { | ||
manualChunks: undefined, | ||
chunkFileNames: '[name].js', | ||
entryFileNames: '[name].js', | ||
assetFileNames: '[name].[ext]', | ||
}, | ||
input: { | ||
app: './assets/js/main.js' | ||
} | ||
} | ||
}, | ||
} | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./naja"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import type { Naja } from "naja"; | ||
import type { | ||
Ajax, | ||
AjaxEventMap as BaseAjaxEventMap, | ||
BaseRequestParams as AjaxBaseRequestParams, | ||
BeforeEventDetail as BaseBeforeEventDetail, | ||
DatagridPayload, | ||
ErrorEventDetail as BaseErrorEventDetail, | ||
EventDetail, | ||
EventListener, | ||
InteractEventDetail as BaseInteractEventDetail, | ||
Payload, | ||
RequestParams, | ||
Response as AjaxResponse, | ||
SuccessEventDetail as BaseSuccessEventDetail, | ||
} from "../types"; | ||
import { Datagrid } from "../datagrid"; | ||
import { BeforeEvent, ErrorEvent, Payload as NajaPayload, SuccessEvent } from "naja/dist/Naja"; | ||
import { InteractionEvent } from "naja/dist/core/UIHandler"; | ||
|
||
export interface BaseRequestParams extends AjaxBaseRequestParams, Request { | ||
url: string; | ||
method: string; | ||
} | ||
|
||
export interface BeforeEventDetail<D = {}> extends BaseBeforeEventDetail<D> { | ||
params: EventDetail<BeforeEvent> & RequestParams<D>; | ||
} | ||
|
||
export interface InteractEventDetail< | ||
E extends HTMLElement = HTMLElement | ||
> extends BaseInteractEventDetail<E>, EventDetail<InteractionEvent> { | ||
element: E; | ||
} | ||
|
||
export interface SuccessEventDetail< | ||
P = DatagridPayload | ||
> extends BaseSuccessEventDetail<P, Response>, EventDetail<SuccessEvent> { | ||
params: BaseRequestParams; | ||
payload: Payload<P> & NajaPayload; | ||
response: AjaxResponse & Response; | ||
} | ||
|
||
export interface ErrorEventDetail< | ||
E extends Error = Error, | ||
> extends BaseErrorEventDetail<E, Response>, EventDetail<ErrorEvent> { | ||
params: BaseRequestParams; | ||
response: (AjaxResponse & Response) | undefined; | ||
error: E; | ||
} | ||
|
||
export interface AjaxEventMap extends BaseAjaxEventMap { | ||
before: CustomEvent<BeforeEventDetail>; | ||
interact: CustomEvent<InteractEventDetail>; | ||
snippetUpdate: CustomEvent<InteractEventDetail>; | ||
success: CustomEvent<SuccessEventDetail>; | ||
error: CustomEvent<ErrorEventDetail>; | ||
} | ||
|
||
export class NajaAjax<C extends Naja = Naja, G extends Datagrid = Datagrid> extends EventTarget implements Ajax<C, G> { | ||
constructor(public client: C) { | ||
if (!client.VERSION || client.VERSION < 2) { | ||
throw new Error("NajaAjax supports Naja 2 and higher" + (client.VERSION ? `(version ${client.VERSION} provided)` : '')) | ||
} | ||
super(); | ||
} | ||
|
||
onInit() { | ||
this.client.addEventListener('before', (e) => { | ||
return this.dispatch('before', { | ||
params: e.detail | ||
}); | ||
}) | ||
|
||
this.client.uiHandler.addEventListener('interaction', (e) => { | ||
if (!(e.detail.element instanceof HTMLElement)) { | ||
throw new Error("Element is not an instanceof HTMLElement"); | ||
} | ||
|
||
return this.dispatch('interact', { | ||
...e.detail, | ||
element: e.detail.element as HTMLElement // Naja's event has a type of HTMLElement | ||
}) | ||
}) | ||
|
||
|
||
this.client.addEventListener('success', (e) => { | ||
return this.dispatch('success', { | ||
...e.detail, | ||
params: e.detail.request, | ||
payload: e.detail.payload as Payload | ||
}); | ||
}) | ||
|
||
this.client.addEventListener('error', (e) => { | ||
return this.dispatch('error', { | ||
...e.detail, | ||
params: e.detail.request, | ||
response: e.detail.response, | ||
}); | ||
}) | ||
|
||
return this; | ||
} | ||
|
||
async request<D = {}, P = DatagridPayload>(args: RequestParams<D>): Promise<P> { | ||
return await this.client.makeRequest(args.method, args.url, args.data) as P; | ||
} | ||
|
||
async submitForm<E extends HTMLFormElement = HTMLFormElement, P = Payload>(element: E): Promise<P> { | ||
return await this.client.uiHandler.submitForm(element) as P; | ||
} | ||
|
||
dispatch< | ||
K extends string, M extends BaseAjaxEventMap = AjaxEventMap | ||
>(type: K, detail: K extends keyof M ? EventDetail<M[K]> : any, options?: boolean): boolean { | ||
return this.dispatchEvent(new CustomEvent(type, {detail})); | ||
} | ||
|
||
declare addEventListener: <K extends keyof M, M extends BaseAjaxEventMap = AjaxEventMap>( | ||
type: K, | ||
listener: EventListener<this, M[K]>, | ||
options?: boolean | AddEventListenerOptions | ||
) => void; | ||
|
||
declare removeEventListener: <K extends keyof M, M extends BaseAjaxEventMap = AjaxEventMap>( | ||
type: K, | ||
listener: EventListener<this, M[K]>, | ||
options?: boolean | AddEventListenerOptions | ||
) => void; | ||
|
||
declare dispatchEvent: <K extends string, M extends BaseAjaxEventMap = AjaxEventMap>( | ||
event: K extends keyof M ? M[K] : CustomEvent | ||
) => boolean; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
@import "@fortawesome/fontawesome-free/css/all.css"; | ||
@import 'bootstrap/dist/css/bootstrap.css'; | ||
@import 'vanillajs-datepicker/css/datepicker-bs5.css'; | ||
@import './datagrid.css'; |
Oops, something went wrong.