Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

310 create component transfer #371

Merged
merged 55 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
cc1eb35
Upgrade Angular 18 and Bootstrap Italia (#367)
AntoninoBonanno Jul 18, 2024
1211e65
chore: devcontainer fix
valeriocomo Jul 18, 2024
e1d0de0
chore: fix devcontainer
valeriocomo Jul 18, 2024
a69ca71
chore: devcontainer fix
valeriocomo Jul 18, 2024
4034945
chore: devcontainer fix
valeriocomo Jul 18, 2024
2116ed5
chore: creazione componente
valeriocomo Jul 19, 2024
6047126
fix: import/export component in module
valeriocomo Jul 19, 2024
4b7bfda
chore: transfer component seup
valeriocomo Jul 19, 2024
3591b57
chore: transfer component setup
valeriocomo Jul 19, 2024
5126e5c
chore: setup examples
valeriocomo Jul 22, 2024
ac756ea
chore: setup transfer list
valeriocomo Jul 22, 2024
fe705f0
feat: selection
valeriocomo Jul 22, 2024
4c736f7
fix: reset flag
valeriocomo Jul 22, 2024
0102fc9
fix: transfer handler
valeriocomo Jul 23, 2024
15971fb
chore: backtransfer setup
valeriocomo Jul 23, 2024
f07cf52
chore: reset setup
valeriocomo Jul 23, 2024
9f52812
chore: title setup
valeriocomo Jul 23, 2024
97c7620
fix: track by
valeriocomo Jul 23, 2024
b7af1fe
chore: title setup
valeriocomo Jul 23, 2024
87de811
fix: selection
valeriocomo Jul 23, 2024
1addbfb
chore: fix selection
valeriocomo Jul 23, 2024
7503747
fix: selection
valeriocomo Jul 23, 2024
46022ee
feat: selectAll Feature
valeriocomo Jul 23, 2024
790d4c3
chore: devcontainer tweak
valeriocomo Jul 23, 2024
09e9440
chore: reactive implementation
valeriocomo Jul 24, 2024
89e7ff7
chore: reactive implementation
valeriocomo Jul 24, 2024
4fc2683
chore: comments
valeriocomo Jul 24, 2024
64d8ae3
chore: comments
valeriocomo Jul 24, 2024
1a64afb
chore: control value accessor
valeriocomo Jul 25, 2024
70da88f
chore: control value accessor examples
valeriocomo Jul 25, 2024
4de4e58
chore: disable select all
valeriocomo Jul 25, 2024
a96f5e2
chore: example splitted
valeriocomo Jul 26, 2024
17eff8b
chore: default example
valeriocomo Jul 26, 2024
5e184da
chore: ref examples
valeriocomo Jul 26, 2024
50204f2
chore: rew
valeriocomo Jul 26, 2024
7c1ec41
chore: transfer examples component template generation
valeriocomo Jul 26, 2024
eee51fa
chore: typo
valeriocomo Jul 26, 2024
6cece36
chore: minor fixes
valeriocomo Jul 26, 2024
1bfb3e0
chore: removing async pipe
valeriocomo Jul 26, 2024
4e16df1
chore: api docs
valeriocomo Jul 26, 2024
b4148c8
chore: json print removed
valeriocomo Jul 26, 2024
d24b40e
chore: fix on example
valeriocomo Jul 26, 2024
d272cb1
fix: transfer tests
valeriocomo Jul 26, 2024
71aef11
fix: test fixed
valeriocomo Jul 26, 2024
6d41498
fix: test
valeriocomo Jul 26, 2024
1ce285d
chore: ref aria setup
valeriocomo Jul 29, 2024
f342138
fix: rework
valeriocomo Jul 29, 2024
7e1a074
fix: seleted
valeriocomo Jul 29, 2024
915c1aa
chore: fix
valeriocomo Jul 29, 2024
3abeb6b
chore: renaming
valeriocomo Jul 29, 2024
b582d59
chore: ref
valeriocomo Jul 29, 2024
ef9d4ef
Merge branch 'main' into 310-create-component-transfer
valeriocomo Jul 29, 2024
0ba3033
fix: build:lib fixed
valeriocomo Jul 30, 2024
ebbf885
fix: removed unused code
valeriocomo Jul 30, 2024
6414c00
fix: new component interface
valeriocomo Jul 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 34 additions & 36 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
{
"name": "design-angular-kit",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
// "image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bookworm",
"build": {
"dockerfile": "Dockerfile"
},
// Features to add to the dev container. More info: https://containers.dev/features.
"features": {
"ghcr.io/devcontainers-contrib/features/angular-cli:2": {
"version": "18.0.7"
},
"ghcr.io/devcontainers-contrib/features/cz-cli:1": {}
},
"mounts": [
"source=design-angular-kit-bundle-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume" // deps volume
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "sh .devcontainer/scripts/postCreateCommand.sh",
// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"angular.ng-template",
"cyrilletuzi.angular-schematics",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"vivaxy.vscode-conventional-commits"
]
}
}
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
"name": "design-angular-kit",
"build": {
"dockerfile": "Dockerfile"
},
"mounts": [
"source=design-angular-kit-bundle-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume" // deps volume
],
"remoteUser": "root",
"postCreateCommand": "sh .devcontainer/scripts/postCreateCommand.sh",
// "postStartCommand": "/bin/bash -c '.devcontainer/scripts/postStartCommand.sh \"${containerWorkspaceFolder}\"'",
"postStartCommand": "sh .devcontainer/scripts/postStartCommand.sh \"${containerWorkspaceFolder}\"",
"customizations": {
"vscode": {
"extensions": [
"angular.ng-template",
"cyrilletuzi.angular-schematics",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"vivaxy.vscode-conventional-commits"
],
"settings": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "always"
}
}
}
},
"features": {
"ghcr.io/devcontainers-contrib/features/angular-cli:2": {
"version": "18.0.7"
},
"ghcr.io/devcontainers-contrib/features/cz-cli:1": {}
}
}
11 changes: 7 additions & 4 deletions .devcontainer/scripts/postCreateCommand.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#/bin/bash
echo "lifecycle hook: postCreateCommand => start"

echo "Set node_modules permission"
sudo chown -R node:node node_modules
echo "Set node_modules permission: done"
# echo "Set node_modules permission"
# sudo chown -R node:node node_modules
# echo "Set node_modules permission: done"

echo "Installing deps"
npm i
echo "Installing deps: done"
echo "Installing deps: done"

echo "lifecycle hook: postCreateCommand => done"
9 changes: 9 additions & 0 deletions .devcontainer/scripts/postStartCommand.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

WORKSPACE_FOLDER=$1

echo "lifecycle hook: postStartCommand => start"
echo "Set $WORKSPACE_FOLDER as git safe directory"
git config --global --add safe.directory $WORKSPACE_FOLDER
# git config --global --add safe.directory /workspaces/design-angular-kit
echo "lifecycle hook: postStartCommand => done"
3 changes: 2 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"buildTarget": "design-angular-kit-bundle:build"
"buildTarget": "design-angular-kit-bundle:build",
"host": "127.0.0.1"
},
"configurations": {
"production": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ItTextareaComponent } from './textarea/textarea.component';
import { ItUploadDragDropComponent } from './upload-drag-drop/upload-drag-drop.component';
import { ItUploadFileListComponent } from './upload-file-list/upload-file-list.component';
import { ItAutocompleteComponent } from './autocomplete/autocomplete.component';
import { ItTransferComponent } from './transfer/transfer.component';

const formComponents = [
ItAutocompleteComponent,
Expand All @@ -21,6 +22,7 @@ const formComponents = [
ItRatingComponent,
ItSelectComponent,
ItTextareaComponent,
ItTransferComponent,
ItUploadDragDropComponent,
ItUploadFileListComponent,
];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
import { TransferItem, TransferItemSelection } from '../transfer.model';
import { SelectionState, State } from './transfer.state';

//#region private utility functions
const generateSelectAll = <T>(checked: boolean, items: TransferItem<T>[]) => {
const selected = new Set<TransferItem<T>>();
if (checked) {
items.forEach(item => selected.add(item));
}

return selected;
};

const updateSelected = <T>(set: Set<TransferItem<T>>, item: TransferItem<T>) => {
if (set.has(item)) {
set.delete(item);
} else {
set.add(item);
}

return set;
};
//#endregion

//#region reducers
const init = <T>(state: State<T>, { source, target }: SelectionState<T>) => ({
...state,
initialItems: {
source: [...source],
target: [...target],
},
current: {
source: [...source],
target: [...target],
},
});

const transfer = <T>(state: State<T>) => {
return {
...state,
current: {
...state.current,
source: state.current.source.filter(i => !state.selections.source.has(i)),
target: Array.from(new Set([...state.current.target, ...Array.from(state.selections.source)] as TransferItemSelection<T>)),
},
selections: {
...state.selections,
source: new Set<TransferItem<T>>(),
},
operationsEnabled: {
...state.operationsEnabled,
transfer: false,
reset: true,
},
} satisfies State<T>;
};

const backtransfer = <T>(state: State<T>) => {
return {
...state,
current: {
...state.current,
target: state.current.target.filter(i => !state.selections.target.has(i)),
source: Array.from(new Set([...state.current.source, ...Array.from(state.selections.target)] as TransferItemSelection<T>)),
},
selections: {
...state.selections,
target: new Set<TransferItem<T>>(),
},
operationsEnabled: {
...state.operationsEnabled,
backtransfer: false,
reset: true,
},
} satisfies State<T>;
};

const reset = <T>(state: State<T>) => {
return {
...state,
current: {
source: [...state.initialItems.source],
target: [...state.initialItems.target],
},
operationsEnabled: {
...state.operationsEnabled,
reset: false,
},
} satisfies State<T>;
};

const selectAllSource = <T>(state: State<T>, { checked }: { checked: boolean }) => {
const items = state.current.source;
const selected = generateSelectAll(checked, items);
const transfer = Boolean(selected.size);

return {
...state,
selections: {
...state.selections,
source: selected,
},
operationsEnabled: {
...state.operationsEnabled,
transfer,
},
} satisfies State<T>;
};

const selectAllTarget = <T>(state: State<T>, { checked }: { checked: boolean }) => {
const items = state.current.target;
const selected = generateSelectAll(checked, items);
const backtransfer = Boolean(selected.size);

return {
...state,
selections: {
...state.selections,
target: selected,
},
operationsEnabled: {
...state.operationsEnabled,
backtransfer,
},
} satisfies State<T>;
};

const selectionItemSource = <T>(previousState: State<T>, { item }: { item: TransferItem<T> }) => {
const selected = updateSelected(previousState.selections.source, item);
const selectedItems = Array.from(selected);
const transfer = Boolean(selectedItems.length);
const source = new Set([...selectedItems]);

const state = {
...previousState,
selections: {
...previousState.selections,
source,
},
operationsEnabled: {
...previousState.operationsEnabled,
transfer,
},
} satisfies State<T>;

return state;
};

const selectionItemTarget = <T>(previousState: State<T>, { item }: { item: TransferItem<T> }) => {
const selected = updateSelected(previousState.selections.target, item);
const selectedItems = Array.from(selected);
const backtransfer = Boolean(selectedItems.length);
const target = new Set([...selectedItems]);

const state = {
...previousState,
selections: {
...previousState.selections,
target,
},
operationsEnabled: {
...previousState.operationsEnabled,
backtransfer,
},
} satisfies State<T>;

return state;
};
//#endregion reducers

//#region public reducers
const initialStateFn = <T>() => ({
initialItems: {
source: [],
target: [],
},
current: {
source: [],
target: [],
},
selections: {
source: new Set<TransferItem<T>>(),
target: new Set<TransferItem<T>>(),
},
operationsEnabled: {
transfer: false,
backtransfer: false,
reset: false,
},
});
const initFn =
<T>(payload: SelectionState<T>) =>
(state: State<T>) =>
init(state, payload);

const transferFn =
<T>() =>
(state: State<T>) =>
transfer(state);

const backtransferFn =
<T>() =>
(state: State<T>) =>
backtransfer(state);

const resetFn =
<T>() =>
(state: State<T>) =>
reset(state);

const selectAllSourceFn =
<T>({ checked }: { checked: boolean }) =>
(state: State<T>) =>
selectAllSource(state, { checked }) as State<T>;

const selectAllTargetFn =
<T>({ checked }: { checked: boolean }) =>
(state: State<T>) =>
selectAllTarget(state, { checked }) as State<T>;

const selectionItemSourceFn =
<T>({ item }: { item: TransferItem<T> }) =>
(state: State<T>) =>
selectionItemSource(state, { item }) as State<T>;

const selectionItemTargetFn =
<T>({ item }: { item: TransferItem<T> }) =>
(state: State<T>) =>
selectionItemTarget(state, { item }) as State<T>;
//#endregion

export default {
initialStateFn,
initFn,
transferFn,
backtransferFn,
resetFn,
selectAllSourceFn,
selectAllTargetFn,
selectionItemSourceFn,
selectionItemTargetFn,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { TransferItem } from '../transfer.model';

export interface SelectionState<T> {
source: Array<TransferItem<T>>;
target: Array<TransferItem<T>>;
}

export interface State<T> {
initialItems: SelectionState<T>;
current: SelectionState<T>;
selections: {
source: Set<TransferItem<T>>;
target: Set<TransferItem<T>>;
};
operationsEnabled: {
transfer: boolean;
backtransfer: boolean;
reset: boolean;
};
}
Loading
Loading