icon-selector/icon-selector.component.ts

Implements

OnInit OnDestroy

Metadata

Relationships

<div
  class="p-l-24 p-r-24 p-t-8 p-b-8 separator-bottom sticky-top"
  style="background: var(--c8y-root-component-background-default); z-index: 2"
>
  <div class="row d-flex-sm">
    <div class="col-sm-5 m-b-8">
      <div
        class="input-group-search input-group"
        style="width: auto"
      >
        <label
          class="sr-only"
          for="filter-icons"
          translate
          >Filter icons</label
        >
        <input
          class="form-control"
          id="filter-icons"
          placeholder="{{ 'Type to filter icons…' | translate }}"
          type="search"
          [ngModel]="searchTerm$ | async"
          (ngModelChange)="onSearchChange($event)"
        />
        @if (searchTerm$ | async) {
          <button
            class="input-group-addon"
            [attr.aria-label]="'Clear search' | translate"
            type="button"
            (click)="onSearchChange('')"
          >
            <i
              c8yIcon="times"
              aria-hidden="true"
            ></i>
          </button>
        } @else {
          <span
            class="input-group-addon"
            aria-hidden="true"
          >
            <i
              c8yIcon="search"
              aria-hidden="true"
            ></i>
          </span>
        }
      </div>
    </div>
    <div class="col-sm-7 m-b-8">
      <div class="d-flex a-i-center j-c-end gap-16 text-left">
        <div class="d-flex a-i-center flex-grow">
          <label
            class="m-b-0 m-r-8 flex-no-shrink"
            id="icon-category-filter-label"
            translate
            >Collection</label
          >
          <c8y-select
            class="flex-grow"
            [attr.aria-labelledby]="'icon-category-filter-label'"
            [items]="availableIconCategoryItems$ | async"
            [selected]="selectedIconCategory$ | async"
            [canDeselect]="true"
            (onSelect)="onCategoryFilterChanged($any($event).value)"
            (onDeselect)="onCategoryFilterChanged(allIconCategory)"
          ></c8y-select>
        </div>

        @if (isAdmin()) {
          <button
            class="btn btn-clean p-l-8 p-r-8 flex-no-shrink"
            [title]="'Add custom icon' | translate"
            [attr.aria-label]="'Add custom icon' | translate"
            type="button"
            (click)="onAddIconClicked()"
          >
            <i
              class="m-r-4"
              c8yIcon="plus-circle"
              aria-hidden="true"
            ></i>
            <span translate>Add icon</span>
          </button>
          <button
            class="btn btn-clean flex-no-shrink"
            [attr.aria-label]="'Import icons from ZIP' | translate"
            [tooltip]="'Import icons from ZIP' | translate"
            placement="top"
            container="body"
            type="button"
            [delay]="500"
            [adaptivePosition]="false"
            (click)="onImportClicked()"
          >
            <i
              class="m-r-4"
              c8yIcon="data-import"
              aria-hidden="true"
            ></i>
            <span>{{ 'Import`verb, imports icons from a ZIP file`' | translate }}</span>
          </button>
          @if (hasCustomIcons()) {
            <button
              class="btn btn-clean flex-no-shrink"
              [attr.aria-label]="'Export custom icons as ZIP' | translate"
              [tooltip]="'Export custom icons as ZIP' | translate"
              placement="top"
              container="body"
              type="button"
              [delay]="500"
              [adaptivePosition]="false"
              (click)="onExportClicked()"
            >
              <i
                class="m-r-4"
                c8yIcon="data-export"
                aria-hidden="true"
              ></i>
              <span>{{ 'Export`verb, exports custom icons as a ZIP file`' | translate }}</span>
            </button>
          }
        }
      </div>
    </div>
  </div>

  @if (isSaving()) {
    <div
      class="p-absolute m-t-4 p-b-4 overflow-hidden"
      style="left: 0; right: 0"
      [attr.aria-label]="'Saving…' | translate"
      role="status"
    >
      <c8y-loading layout="page"></c8y-loading>
    </div>
  }
</div>

<div class="p-16">
  @if (iconsLoading()) {
    <div
      class="d-flex a-i-center j-c-center p-32"
      [attr.aria-label]="'Loading icons…' | translate"
      role="status"
    >
      <c8y-loading></c8y-loading>
    </div>
  } @else {
    <p
      class="sr-only"
      role="status"
    >
      @if (filteredIconCount() === 0) {
        {{ 'No icons found' | translate }}
      } @else {
        {{ '{{count}} icon(s) found' | translate: { count: filteredIconCount() } }}
      }
    </p>
    <section
      class="dtm-icon-grid"
      [attr.aria-label]="'Icon grid' | translate"
      [attr.aria-busy]="visibleDefinitions().length === 0 ? 'true' : null"
      role="region"
    >
      @for (iconDefinition of visibleDefinitions(); track iconDefinition.label) {
        <div
          class="d-contents"
          [attr.aria-label]="iconDefinition.label | translate"
          role="group"
        >
          <div class="legend form-block center grid__col--fullspan d-flex a-i-center gap-8">
            {{ iconDefinition.label | translate }}
            @if (customCategoryLabels().has(iconDefinition.label)) {
              <span class="tag tag--info m-l-4 m-t-0 m-b-0">{{
                'Custom`badge indicating a user-added icon category`' | translate
              }}</span>
            }
          </div>

          @for (icon of iconDefinition.icons; track icon[0]) {
            @let isCustom = isCustomIcon(icon[0]);
            @let isOverridden = isIconOverridden(icon[0]);
            @let overriddenLabel = gettext('{{name}} (overridden)');
            @let deleteHint = 'Select a different icon before deleting this one.' | translate;
            <div class="d-contents">
              <div
                class="dtm-icon-grid__item"
                [class.dtm-icon-grid__item--selected]="selectedIcon && icon[0] === selectedIcon"
                [class.dtm-icon-grid__item--overridden]="isOverridden"
              >
                <button
                  class="dtm-icon-grid__btn"
                  [title]="icon[0] | iconName"
                  [attr.aria-label]="
                    isOverridden
                      ? (overriddenLabel | translate: { name: icon[0] | iconName })
                      : (icon[0] | iconName)
                  "
                  [attr.aria-current]="selectedIcon && icon[0] === selectedIcon ? 'true' : null"
                  (click)="onIconClicked(icon)"
                >
                  <i
                    class="icon-40 c8y-icon-duocolor"
                    [c8yIcon]="icon[0]"
                    aria-hidden="true"
                  ></i>
                  @if (showIconClass) {
                    <small
                      class="d-block text-center text-break-word"
                      aria-hidden="true"
                    >
                      {{ icon[0] | iconName }}
                    </small>
                  }
                </button>

                @if (isOverridden) {
                  <span
                    class="dtm-icon-grid__override-marker"
                    [tooltip]="'Overridden icon' | translate"
                    placement="top"
                    container="body"
                    aria-hidden="true"
                    [delay]="500"
                  >
                    <i c8yIcon="replace"></i>
                  </span>
                }

                @if (isAdmin()) {
                  <div
                    class="dtm-icon-grid__actions"
                    [attr.aria-label]="'{{name}} actions' | translate: { name: icon[0] | iconName }"
                    role="group"
                  >
                    @if (isCustom) {
                      <button
                        class="btn btn-dot"
                        [attr.aria-label]="
                          'Edit {{name}}' | translate: { name: icon[0] | iconName }
                        "
                        [tooltip]="'Edit {{name}}' | translate: { name: icon[0] | iconName }"
                        placement="top"
                        container="body"
                        type="button"
                        [delay]="500"
                        (click)="$event.stopPropagation(); onEditIconClicked(icon[0])"
                      >
                        <i
                          c8yIcon="pencil"
                          aria-hidden="true"
                        ></i>
                      </button>
                      <span
                        [tooltip]="icon[0] === selectedIcon ? deleteHint : null"
                        placement="top"
                        container="body"
                        [delay]="500"
                      >
                        <button
                          class="btn btn-dot btn-dot--danger m-0"
                          [class.disabled]="icon[0] === selectedIcon"
                          [attr.aria-label]="
                            'Delete {{name}}' | translate: { name: icon[0] | iconName }
                          "
                          [tooltip]="'Delete {{name}}' | translate: { name: icon[0] | iconName }"
                          placement="top"
                          container="body"
                          [attr.aria-disabled]="icon[0] === selectedIcon ? 'true' : null"
                          [attr.aria-describedby]="
                            icon[0] === selectedIcon ? 'delete-hint-' + icon[0] : null
                          "
                          type="button"
                          [delay]="500"
                          (click)="
                            $event.stopPropagation();
                            icon[0] === selectedIcon || onDeleteIconClicked(icon[0])
                          "
                        >
                          <i
                            c8yIcon="minus-circle"
                            aria-hidden="true"
                          ></i>
                        </button>
                        @if (icon[0] === selectedIcon) {
                          <span
                            class="sr-only"
                            [id]="'delete-hint-' + icon[0]"
                            >{{ deleteHint }}</span
                          >
                        }
                      </span>
                    } @else {
                      @let overrideKey =
                        isOverridden
                          ? gettext('Replace override for {{name}}')
                          : gettext('Override {{name}}');
                      <button
                        class="btn btn-dot"
                        [attr.aria-label]="overrideKey | translate: { name: icon[0] | iconName }"
                        [tooltip]="overrideKey | translate: { name: icon[0] | iconName }"
                        placement="top"
                        container="body"
                        type="button"
                        [delay]="500"
                        (click)="$event.stopPropagation(); onOverrideIconClicked(icon)"
                      >
                        <i
                          c8yIcon="replace"
                          aria-hidden="true"
                        ></i>
                      </button>
                      @if (isOverridden) {
                        <button
                          class="btn btn-dot btn-dot--danger"
                          [attr.aria-label]="
                            'Reset override for {{name}}' | translate: { name: icon[0] | iconName }
                          "
                          [tooltip]="
                            'Reset override for {{name}}' | translate: { name: icon[0] | iconName }
                          "
                          placement="top"
                          container="body"
                          type="button"
                          [delay]="500"
                          (click)="$event.stopPropagation(); onResetOverrideClicked(icon[0])"
                        >
                          <i
                            c8yIcon="undo"
                            aria-hidden="true"
                          ></i>
                        </button>
                      }
                    }
                  </div>
                }
              </div>
            </div>
          }
        </div>
      } @empty {
        <c8y-ui-empty-state
          class="grid__col--fullspan"
          icon="search"
          [title]="'No icons found' | translate"
          [subtitle]="
            'Try adjusting your search or filter to find what you\'re looking for.' | translate
          "
          [horizontal]="true"
        ></c8y-ui-empty-state>
      }
    </section>
  }
  <!-- end @else iconsLoading -->
</div>

results matching ""

    No results matching ""