Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
y509144 authored Feb 10, 2023
1 parent eed6703 commit 5ec416c
Show file tree
Hide file tree
Showing 4 changed files with 385 additions and 0 deletions.
22 changes: 22 additions & 0 deletions widget/icon-selector/icon-selector.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<ng-select
#select
[items]="items"
[ngModel]="value"
(ngModelChange)="valueChange.emit($event)"
[appendTo]="appendTo ? appendTo : 'body'"
[clearable]="false"
[virtualScroll]="true"
(open)="opened(select)"
bindLabel="name"
bindValue="className"
>
<ng-template ng-label-tmp let-item="item">
<i [c8yIcon]="item.className" style="margin-right: 5px"></i>
<span>{{ item.name }}</span>
</ng-template>

<ng-template ng-option-tmp let-item="item" let-index="index" let-search="searchTerm">
<i [c8yIcon]="item.className" style="margin-right: 5px"></i>
<span>{{ item.name }} ({{ item.className }})</span>
</ng-template>
</ng-select>
52 changes: 52 additions & 0 deletions widget/icon-selector/icon-selector.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2019 Software AG, Darmstadt, Germany and/or its licensors
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { Component, EventEmitter, Input, Output } from '@angular/core';

import * as fa from 'fontawesome';
import * as icons from './ignore-font-icons';
@Component({
selector: 'lib-icon-selector',
templateUrl: './icon-selector.component.html',
})
export class IconSelectorComponent {
@Input() value: string;
@Input() appendTo: string;
@Output() valueChange = new EventEmitter<string>();

// Create a list of all icons
items = Object.keys(fa)
.filter((name) => !['html5', 's15', '500px'].includes(name))
.map((name) => name.replace(/[A-Z0-9]/g, (match) => '-' + match.toLowerCase()))
.concat(['html5', 's15', '500px'])
.filter((name) => !icons.ignoreIcons.includes(name))
.sort()
.map((name) => ({
name: name.replace(/-/g, ' ').replace(/\b[a-z]/g, (match) => match.toUpperCase()),
className: name.toLowerCase(),
}));
opened(select): void {
setTimeout(() => {
try {
select.dropdownPanel._updatePosition();
} catch (e) {
// Ignore error
}
}, 25);
}
}
205 changes: 205 additions & 0 deletions widget/icon-selector/ignore-font-icons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/**
* Copyright (c) 2020 Software AG, Darmstadt, Germany and/or its licensors
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export const ignoreIcons = [
'500px',
'adn',
'amazon',
'android',
'angellist',
'apple',
'bandcamp',
'behance',
'behance-square',
'bitbucket',
'bitbucket-square',
'black-tie',
'buysellads',
'cc-diners-club',
'cc-jcb',
'chrome',
'codepen',
'codiepie',
'connectdevelop',
'contao',
'css-3',
'delicious',
'deviantart',
'digg',
'dribbble',
'dropbox',
'drupal',
'edge',
'eercast',
'empire',
'envira',
'etsy',
'expeditedssl',
'external-link-square',
'fa',
'facebook-f',
'facebook-official',
'facebook-square',
'firefox',
'first-order',
'flickr',
'font-awesome',
'fonticons',
'fort-awesome',
'forumbee',
'foursquare',
'free-code-camp',
'ge',
'genderless',
'get-pocket',
'gg',
'gg-circle',
'git',
'git-square',
'github-alt',
'github-square',
'gitlab',
'gittip',
'glide',
'glide-g',
'google-plus',
'google-plus-circle',
'google-plus-official',
'google-plus-square',
'gratipay',
'grav',
'hacker-news',
'houzz',
'html5',
'imdb',
'internet-explorer',
'intersex',
'ioxhost',
'joomla',
'jsfiddle',
'lastfm',
'lastfm-square',
'leanpub',
'life-bouy',
'linkedin-square',
'linode',
'linux',
'mars',
'mars-double',
'mars-stroke',
'mars-stroke-h',
'mars-stroke-v',
'maxcdn',
'meanpath',
'medium',
'meetup',
'mercury',
'mixcloud',
'modx',
'neuter',
'odnoklassniki',
'odnoklassniki-square',
'opencart',
'openid',
'opera',
'optin-monster',
'pagelines',
'pause-circle-o',
'pied-piper',
'pied-piper-alt',
'pied-piper-pp',
'pinterest-p',
'pinterest-square',
'product-hunt',
'qq',
'quora',
'ra',
'ravelry',
'rebel',
'reddit',
'reddit-alien',
'reddit-square',
'registered',
'renren',
'resistance',
'safari',
'scribd',
'sellsy',
'shirtsinbulk',
'simplybuilt',
'skyatlas',
'skype',
'slack',
'slideshare',
'snapchat',
'snapchat-ghost',
'snapchat-square',
'soundcloud',
'spotify',
'stack-exchange',
'stack-overflow',
'steam',
'steam-square',
'stop-circle-o',
'stumbleupon',
'stumbleupon-circle',
'subway',
'superpowers',
'telegram',
'tencent-weibo',
'themeisle',
'transgender',
'transgender-alt',
'trello',
'tripadvisor',
'tumblr',
'tumblr-square',
'twitch',
'twitter-square',
'usb',
'venus',
'venus-double',
'venus-mars',
'viacoin',
'viadeo',
'viadeo-square',
'vimeo',
'vimeo-square',
'vine',
'vk',
'wechat',
'weibo',
'weixin',
'whatsapp',
'wikipedia-w',
'windows',
'wordpress',
'wpbeginner',
'wpexplorer',
'wpforms',
'xing',
'xing-square',
'y-combinator',
'y-combinator-square',
'yahoo',
'yc',
'yc-square',
'yelp',
'yoast',
'youtube-square',
];
106 changes: 106 additions & 0 deletions widget/icon-selector/selection-model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2019 Software AG, Darmstadt, Germany and/or its licensors
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NgOption } from "@ng-select/ng-select";

export type SelectionModelFactory = () => SelectionModel;

export function DefaultSelectionModelFactory() {
return new DefaultSelectionModel();
}

export interface SelectionModel {
value: NgOption[];
select(item: NgOption, multiple: boolean, selectableGroupAsModel: boolean);
unselect(item: NgOption, multiple: boolean);
clear(keepDisabled: boolean);
}

export class DefaultSelectionModel implements SelectionModel {
private _selected: NgOption[] = [];

get value(): NgOption[] {
return this._selected;
}

select(item: NgOption, multiple: boolean, groupAsModel: boolean) {
item.selected = true;
if (!item.children || (!multiple && groupAsModel)) {
this._selected.push(item);
}
if (multiple) {
if (item.parent) {
const childrenCount = item.parent.children.length;
const selectedCount = item.parent.children.filter(x => x.selected).length;
item.parent.selected = childrenCount === selectedCount;
} else if (item.children) {
this._setChildrenSelectedState(item.children, true);
this._removeChildren(item);
if (groupAsModel && this._activeChildren(item)) {
this._selected = [...this._selected.filter(x => x.parent !== item), item]
} else {
this._selected = [...this._selected, ...item.children.filter(x => !x.disabled)];
}
}
}
}

unselect(item: NgOption, multiple: boolean) {
this._selected = this._selected.filter(x => x !== item);
item.selected = false;
if (multiple) {
if (item.parent && item.parent.selected) {
const children = item.parent.children;
this._removeParent(item.parent);
this._removeChildren(item.parent);
this._selected.push(...children.filter(x => x !== item && !x.disabled));
item.parent.selected = false;
} else if (item.children) {
this._setChildrenSelectedState(item.children, false);
this._removeChildren(item);
}
}
}

clear(keepDisabled: boolean) {
this._selected = keepDisabled ? this._selected.filter(x => x.disabled) : [];
}

private _setChildrenSelectedState(children: NgOption[], selected: boolean) {
for (const child of children) {
if (child.disabled) {
continue;
}
child.selected = selected;
}
}

private _removeChildren(parent: NgOption) {
this._selected = [
...this._selected.filter(x => x.parent !== parent),
...parent.children.filter(x => x.parent === parent && x.disabled && x.selected)
];
}

private _removeParent(parent: NgOption) {
this._selected = this._selected.filter(x => x !== parent)
}

private _activeChildren(item: NgOption): boolean {
return item.children.every(x => !x.disabled || x.selected);
}
}

0 comments on commit 5ec416c

Please sign in to comment.